mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-23 23:12:31 +00:00
Migrate and refactor more interfaces from batphone
This commit is contained in:
parent
42200c2bcb
commit
46ef40cf23
@ -128,6 +128,8 @@ static int outv_growbuf(struct cli_context *context, size_t needed)
|
||||
|
||||
static int put_blob(struct cli_context *context, jbyte *value, jsize length){
|
||||
jbyteArray arr = NULL;
|
||||
if (context->jni_exception)
|
||||
return -1;
|
||||
if (value && length>0){
|
||||
arr = (*context->jni_env)->NewByteArray(context->jni_env, length);
|
||||
if (arr == NULL || (*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
@ -143,7 +145,7 @@ static int put_blob(struct cli_context *context, jbyte *value, jsize length){
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, putBlob, arr);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
return WHY("Exception thrown from CallVoidMethod()");
|
||||
return WHY("Exception thrown from CallVoidMethod(putBlob)");
|
||||
}
|
||||
if (arr)
|
||||
(*context->jni_env)->DeleteLocalRef(context->jni_env, arr);
|
||||
@ -287,6 +289,7 @@ int parseCommandLine(struct cli_context *context, const char *argv0, int argc, c
|
||||
// Load configuration so that log messages can get out.
|
||||
cf_reload_permissive();
|
||||
NOWHENCE(HINTF("Run \"%s help\" for more information.", argv0 ? argv0 : "servald"));
|
||||
result =-1;
|
||||
break;
|
||||
default:
|
||||
// Load configuration so that log error messages can get out.
|
||||
@ -389,10 +392,13 @@ void cli_columns(struct cli_context *context, int columns, const char *names[])
|
||||
{
|
||||
#ifdef HAVE_JNI_H
|
||||
if (context && context->jni_env) {
|
||||
if (context->jni_exception)
|
||||
return;
|
||||
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, startResultSet, columns);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod()");
|
||||
WHY("Exception thrown from CallVoidMethod(startResultSet)");
|
||||
return;
|
||||
}
|
||||
int i;
|
||||
@ -405,6 +411,11 @@ void cli_columns(struct cli_context *context, int columns, const char *names[])
|
||||
}
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, setColumnName, i, str);
|
||||
(*context->jni_env)->DeleteLocalRef(context->jni_env, str);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod(setColumnName)");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@ -425,6 +436,8 @@ void cli_field_name(struct cli_context *context, const char *name, const char *d
|
||||
{
|
||||
#ifdef HAVE_JNI_H
|
||||
if (context && context->jni_env) {
|
||||
if (context->jni_exception)
|
||||
return;
|
||||
jstring str = (jstring)(*context->jni_env)->NewStringUTF(context->jni_env, name);
|
||||
if (str == NULL) {
|
||||
context->jni_exception = 1;
|
||||
@ -433,6 +446,11 @@ void cli_field_name(struct cli_context *context, const char *name, const char *d
|
||||
}
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, setColumnName, -1, str);
|
||||
(*context->jni_env)->DeleteLocalRef(context->jni_env, str);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod(setColumnName)");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -443,7 +461,13 @@ void cli_field_name(struct cli_context *context, const char *name, const char *d
|
||||
void cli_put_long(struct cli_context *context, int64_t value, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (context && context->jni_env) {
|
||||
if (context->jni_exception)
|
||||
return;
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, putLong, value);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod(putLong)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -454,6 +478,8 @@ void cli_put_long(struct cli_context *context, int64_t value, const char *delim)
|
||||
void cli_put_string(struct cli_context *context, const char *value, const char *delim){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (context && context->jni_env) {
|
||||
if (context->jni_exception)
|
||||
return;
|
||||
jstring str = NULL;
|
||||
if (value){
|
||||
str = (jstring)(*context->jni_env)->NewStringUTF(context->jni_env, value);
|
||||
@ -465,6 +491,10 @@ void cli_put_string(struct cli_context *context, const char *value, const char *
|
||||
}
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, putString, str);
|
||||
(*context->jni_env)->DeleteLocalRef(context->jni_env, str);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod(putLong)");
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -488,12 +518,14 @@ void cli_put_hexvalue(struct cli_context *context, const unsigned char *value, i
|
||||
void cli_row_count(struct cli_context *context, int rows){
|
||||
#ifdef HAVE_JNI_H
|
||||
if (context && context->jni_env) {
|
||||
if (context->jni_exception)
|
||||
return;
|
||||
(*context->jni_env)->CallVoidMethod(context->jni_env, context->jniResults, totalRowCount, rows);
|
||||
if ((*context->jni_env)->ExceptionOccurred(context->jni_env)) {
|
||||
context->jni_exception = 1;
|
||||
WHY("Exception thrown from CallVoidMethod()");
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@ -713,6 +745,14 @@ int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
time_ms_t now;
|
||||
int interval=125;
|
||||
|
||||
const char *names[]={
|
||||
"uri",
|
||||
"did",
|
||||
"name"
|
||||
};
|
||||
cli_columns(context, 3, names);
|
||||
size_t rowcount = 0;
|
||||
|
||||
while (timeout > (now = gettime_ms())){
|
||||
if ((last_tx+interval)<now){
|
||||
lookup_send_request(mdp_sockfd, &srcsid, port, NULL, did);
|
||||
@ -750,6 +790,7 @@ int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
cli_put_string(context, uri, ":");
|
||||
cli_put_string(context, did, ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
rowcount++;
|
||||
|
||||
if (one_reply){
|
||||
timeout=now;
|
||||
@ -775,6 +816,7 @@ int app_dna_lookup(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
}
|
||||
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
cli_row_count(context, rowcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2102,6 +2144,15 @@ int app_keyring_list(const struct cli_parsed *parsed, struct cli_context *contex
|
||||
keyring_file *k = keyring_open_instance_cli(parsed);
|
||||
if (!k)
|
||||
return -1;
|
||||
|
||||
const char *names[]={
|
||||
"sid",
|
||||
"did",
|
||||
"name"
|
||||
};
|
||||
cli_columns(context, 3, names);
|
||||
size_t rowcount = 0;
|
||||
|
||||
unsigned cn, in;
|
||||
for (cn = 0; cn < k->context_count; ++cn)
|
||||
for (in = 0; in < k->contexts[cn]->identity_count; ++in) {
|
||||
@ -2113,9 +2164,11 @@ int app_keyring_list(const struct cli_parsed *parsed, struct cli_context *contex
|
||||
cli_put_string(context, alloca_tohex_sid_t(*sidp), ":");
|
||||
cli_put_string(context, did, ":");
|
||||
cli_put_string(context, name, "\n");
|
||||
rowcount++;
|
||||
}
|
||||
}
|
||||
keyring_free(k);
|
||||
cli_row_count(context, rowcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2397,6 +2450,12 @@ int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
goto end;
|
||||
}
|
||||
|
||||
const char *names[]={
|
||||
"sid"
|
||||
};
|
||||
cli_columns(context, 1, names);
|
||||
size_t rowcount=0;
|
||||
|
||||
time_ms_t timeout=gettime_ms()+500;
|
||||
while(1){
|
||||
struct mdp_header rev_header;
|
||||
@ -2410,8 +2469,8 @@ int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
}
|
||||
|
||||
if (len>=SID_SIZE){
|
||||
rowcount++;
|
||||
sid_t *id = (sid_t*)response_payload;
|
||||
cli_field_name(context, "sid", ":");
|
||||
cli_put_hexvalue(context, id->binary, sizeof(sid_t), "\n");
|
||||
// TODO receive and decode other details about this identity
|
||||
}
|
||||
@ -2421,7 +2480,7 @@ int app_id_list(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cli_row_count(context, rowcount);
|
||||
end:
|
||||
mdp_close(mdp_sock);
|
||||
return ret;
|
||||
@ -2436,7 +2495,6 @@ int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
overlay_mdp_frame a;
|
||||
bzero(&a, sizeof(overlay_mdp_frame));
|
||||
int result;
|
||||
int count=0;
|
||||
|
||||
a.packetTypeAndFlags=MDP_GETADDRS;
|
||||
const char *arg = parsed->labelc ? parsed->labelv[0].text : "";
|
||||
@ -2453,6 +2511,12 @@ int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
if ((mdp_sockfd = overlay_mdp_client_socket()) < 0)
|
||||
return WHY("Cannot create MDP socket");
|
||||
|
||||
const char *names[]={
|
||||
"sid"
|
||||
};
|
||||
cli_columns(context, 1, names);
|
||||
size_t rowcount=0;
|
||||
|
||||
do{
|
||||
result=overlay_mdp_send(mdp_sockfd, &a, MDP_AWAITREPLY, 5000);
|
||||
if (result) {
|
||||
@ -2470,15 +2534,14 @@ int app_id_self(const struct cli_parsed *parsed, struct cli_context *context)
|
||||
}
|
||||
unsigned i;
|
||||
for(i=0;i<a.addrlist.frame_sid_count;i++) {
|
||||
count++;
|
||||
cli_printf(context, "%s", alloca_tohex_sid_t(a.addrlist.sids[i]));
|
||||
cli_delim(context, "\n");
|
||||
rowcount++;
|
||||
cli_put_string(context, alloca_tohex_sid_t(a.addrlist.sids[i]), "\n");
|
||||
}
|
||||
/* get ready to ask for next block of SIDs */
|
||||
a.packetTypeAndFlags=MDP_GETADDRS;
|
||||
a.addrlist.first_sid=a.addrlist.last_sid+1;
|
||||
}while(a.addrlist.frame_sid_count==MDP_MAX_SID_REQUEST);
|
||||
|
||||
cli_row_count(context, rowcount);
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
return 0;
|
||||
}
|
||||
@ -2705,6 +2768,7 @@ int app_route_print(const struct cli_parsed *parsed, struct cli_context *context
|
||||
"Next hop"
|
||||
};
|
||||
cli_columns(context, 4, names);
|
||||
size_t rowcount=0;
|
||||
|
||||
while(overlay_mdp_client_poll(mdp_sockfd, 200)){
|
||||
overlay_mdp_frame rx;
|
||||
@ -2743,9 +2807,11 @@ int app_route_print(const struct cli_parsed *parsed, struct cli_context *context
|
||||
cli_put_string(context, strbuf_str(b), ":");
|
||||
cli_put_string(context, p->interface_name, ":");
|
||||
cli_put_string(context, alloca_tohex_sid_t(p->neighbour), "\n");
|
||||
rowcount++;
|
||||
}
|
||||
}
|
||||
overlay_mdp_client_close(mdp_sockfd);
|
||||
cli_row_count(context, rowcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -96,6 +96,10 @@ public abstract class AbstractId {
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public void toByteBuffer(ByteBuffer buff){
|
||||
buff.put(this.binary);
|
||||
}
|
||||
|
||||
public String toHex(int offset, int len) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = offset; i < offset + len && i < binary.length; i++) {
|
||||
|
@ -20,29 +20,7 @@
|
||||
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
/**
|
||||
* Indicates an internal (coding) error in the JNI interface to servald. Typically encountered when
|
||||
* unpacking the outv strings returned by a servald operation, and indicates that the C code in
|
||||
* servald that constructs the outv array is not consistent with the Java code that unpacks the outv
|
||||
* strings.
|
||||
*/
|
||||
public class ServalDInterfaceError extends Error
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServalDInterfaceError(String message, ServalDResult result) {
|
||||
super(message + ": " + result);
|
||||
}
|
||||
|
||||
public ServalDInterfaceError(String message, ServalDResult result, Throwable cause) {
|
||||
super(message + ": " + result, cause);
|
||||
}
|
||||
|
||||
public ServalDInterfaceError(ServalDResult result, Throwable cause) {
|
||||
super("" + result, cause);
|
||||
}
|
||||
|
||||
public ServalDInterfaceError(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
public interface AsyncResult<T> {
|
||||
public void result(T nextResult);
|
||||
}
|
56
java/org/servalproject/servaldna/JniResult.java
Normal file
56
java/org/servalproject/servaldna/JniResult.java
Normal file
@ -0,0 +1,56 @@
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
/**
|
||||
* Created by jeremy on 18/02/14.
|
||||
*/
|
||||
public class JniResult implements IJniResults{
|
||||
protected String columnName=null;
|
||||
protected String command[];
|
||||
protected int result;
|
||||
|
||||
void setCommand(String command[]){
|
||||
this.command = command;
|
||||
}
|
||||
void setResult(int result) throws ServalDFailureException {
|
||||
this.result = result;
|
||||
if (result == ServalDCommand.STATUS_ERROR)
|
||||
throw new ServalDFailureException("Command \"" + ServalDCommand.toString(command)+"\" returned an error");
|
||||
}
|
||||
|
||||
public int getResult(){
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startResultSet(int columns) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColumnName(int column, String name) {
|
||||
columnName=name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putDouble(double value) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void totalRowCount(int rows) {
|
||||
}
|
||||
}
|
75
java/org/servalproject/servaldna/JniResultList.java
Normal file
75
java/org/servalproject/servaldna/JniResultList.java
Normal file
@ -0,0 +1,75 @@
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
/**
|
||||
* Created by jeremy on 18/02/14.
|
||||
*/
|
||||
public abstract class JniResultList<T extends JniResult> implements IJniResults {
|
||||
private String names[];
|
||||
private int column =-1;
|
||||
private int columns = -1;
|
||||
private T currentRow;
|
||||
private AsyncResult<T> results;
|
||||
|
||||
public JniResultList(AsyncResult<T> results){
|
||||
this.results = results;
|
||||
}
|
||||
public abstract T create();
|
||||
|
||||
@Override
|
||||
public void startResultSet(int columns) {
|
||||
names = new String[columns];
|
||||
this.columns = columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColumnName(int column, String name) {
|
||||
names[column]=name;
|
||||
}
|
||||
|
||||
private void prepareCol(){
|
||||
column++;
|
||||
if (column==0)
|
||||
currentRow = create();
|
||||
currentRow.columnName = names[column];
|
||||
}
|
||||
private void endCol(){
|
||||
if (column+1>=columns){
|
||||
if (currentRow!=null)
|
||||
results.result(currentRow);
|
||||
currentRow=null;
|
||||
column=-1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
prepareCol();
|
||||
currentRow.putString(value);
|
||||
endCol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
prepareCol();
|
||||
currentRow.putBlob(value);
|
||||
endCol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
prepareCol();
|
||||
currentRow.putLong(value);
|
||||
endCol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putDouble(double value) {
|
||||
prepareCol();
|
||||
currentRow.putDouble(value);
|
||||
endCol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void totalRowCount(int rows) {
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class JniResultsList extends AbstractJniResults implements IJniResults {
|
||||
final List<byte[]> list;
|
||||
private byte[] empty = new byte[0];
|
||||
public JniResultsList(List<byte[]> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
list.add(value == null ? empty : value);
|
||||
}
|
||||
|
||||
}
|
@ -20,7 +20,11 @@
|
||||
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ServalDCommand
|
||||
{
|
||||
@ -32,6 +36,28 @@ public class ServalDCommand
|
||||
System.loadLibrary("serval");
|
||||
}
|
||||
|
||||
public static final int STATUS_ERROR = 255;
|
||||
|
||||
public static String toString(String[] values) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (i > 0)
|
||||
sb.append(' ');
|
||||
sb.append(values[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// copies the semantics of serval-dna's confParseBoolean
|
||||
private static boolean parseBoolean(String value, boolean defaultValue) {
|
||||
if (value == null || "".equals(value))
|
||||
return defaultValue;
|
||||
return "off".compareToIgnoreCase(value) != 0
|
||||
&& "no".compareToIgnoreCase(value) != 0
|
||||
&& "false".compareToIgnoreCase(value) != 0
|
||||
&& "0".compareToIgnoreCase(value) != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Low-level JNI entry point into servald command line.
|
||||
*
|
||||
@ -39,8 +65,7 @@ public class ServalDCommand
|
||||
* @param args The words to pass on the command line (ie, argv[1]...argv[n])
|
||||
* @return The servald exit status code (normally 0 indicates success)
|
||||
*/
|
||||
private static native int rawCommand(IJniResults results, String[] args)
|
||||
throws ServalDInterfaceError;
|
||||
private static native int rawCommand(IJniResults results, String[] args);
|
||||
|
||||
/**
|
||||
* Common entry point into servald command line.
|
||||
@ -54,39 +79,577 @@ public class ServalDCommand
|
||||
* @return The servald exit status code (normally0 indicates success)
|
||||
*/
|
||||
public static synchronized int command(final IJniResults callback, String... args)
|
||||
throws ServalDInterfaceError
|
||||
throws ServalDFailureException {
|
||||
int ret = ServalDCommand.rawCommand(callback, args);
|
||||
if (ret == STATUS_ERROR)
|
||||
throw new ServalDFailureException("Command \"" + toString(args)+"\" returned an error");
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static synchronized JniResult command(String... args)
|
||||
throws ServalDFailureException {
|
||||
JniResult result = new JniResult();
|
||||
result.setCommand(args);
|
||||
result.setResult(ServalDCommand.rawCommand(result, args));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class Status extends JniResult{
|
||||
public int pid;
|
||||
public int tries;
|
||||
public String instancePath;
|
||||
public String status;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
if (columnName.equals("instancepath"))
|
||||
instancePath=value;
|
||||
if (columnName.equals("status"))
|
||||
status=value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
if (columnName.equals("pid"))
|
||||
pid = (int)value;
|
||||
if (columnName.equals("tries"))
|
||||
tries = (int)value;
|
||||
}
|
||||
}
|
||||
|
||||
/** Start the servald server process if it is not already running.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
public static Status serverStart(String execPath)
|
||||
throws ServalDFailureException {
|
||||
Status result = new Status();
|
||||
result.setResult(command(result, "start", "exec", execPath));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Status serverStop()
|
||||
throws ServalDFailureException {
|
||||
Status result = new Status();
|
||||
result.setResult(command(result, "stop"));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Status serverStatus()
|
||||
throws ServalDFailureException {
|
||||
Status result = new Status();
|
||||
result.setResult(command(result, "status"));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class IdentityResult extends JniResult {
|
||||
public String did;
|
||||
public String name;
|
||||
public SubscriberId subscriberId;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
if (this.columnName.equals("did"))
|
||||
this.did = value;
|
||||
if (this.columnName.equals("name"))
|
||||
this.name = value;
|
||||
if (this.columnName.equals("sid"))
|
||||
try {
|
||||
this.subscriberId = new SubscriberId(value);
|
||||
} catch (AbstractId.InvalidHexException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
if (this.columnName.equals("sid"))
|
||||
try {
|
||||
this.subscriberId = new SubscriberId(value);
|
||||
} catch (AbstractId.InvalidBinaryException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static IdentityResult keyringAdd()
|
||||
throws ServalDFailureException {
|
||||
IdentityResult result = new IdentityResult();
|
||||
command(result, "keyring", "add");
|
||||
return result;
|
||||
}
|
||||
|
||||
public static IdentityResult keyringSetDidName(SubscriberId sid, String did, String name) throws ServalDFailureException
|
||||
{
|
||||
return ServalDCommand.rawCommand(callback, args);
|
||||
IdentityResult result = new IdentityResult();
|
||||
command(result, "keyring","set","did", sid.toHex(), did==null?"":did, name==null?"":name);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int keyringList(final AsyncResult<IdentityResult> results) throws ServalDFailureException
|
||||
{
|
||||
return keyringList(new JniResultList<IdentityResult>(results) {
|
||||
@Override
|
||||
public IdentityResult create() {
|
||||
return new IdentityResult();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static int keyringList(IJniResults results) throws ServalDFailureException{
|
||||
return command(results, "keyring", "list");
|
||||
}
|
||||
|
||||
public static IdentityResult reverseLookup(final SubscriberId sid) throws ServalDFailureException {
|
||||
IdentityResult result = new IdentityResult();
|
||||
command(result, "reverse", "lookup", sid.toHex());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class LookupResult extends JniResult {
|
||||
public String did;
|
||||
public String name;
|
||||
public String uri;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
if (this.columnName.equals("did"))
|
||||
this.did = value;
|
||||
if (this.columnName.equals("name"))
|
||||
this.name = value;
|
||||
if (this.columnName.equals("uri"))
|
||||
this.uri = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int dnaLookup(AsyncResult<LookupResult> results, String did, int timeout) throws ServalDFailureException {
|
||||
return dnaLookup(new JniResultList<LookupResult>(results) {
|
||||
@Override
|
||||
public LookupResult create() {
|
||||
return new LookupResult();
|
||||
}
|
||||
}, did, timeout);
|
||||
}
|
||||
|
||||
public static int dnaLookup(IJniResults results, String did, int timeout) throws ServalDFailureException {
|
||||
return command(results, "dna", "lookup", did, Integer.toString(timeout));
|
||||
}
|
||||
public static class ManifestResult extends JniResult{
|
||||
public BundleId manifestId;
|
||||
public long version;
|
||||
public long fileSize;
|
||||
public FileHash fileHash;
|
||||
public BundleKey bundleKey;
|
||||
public long date;
|
||||
public int crypt;
|
||||
public String service;
|
||||
public String name;
|
||||
public boolean readonly=true;
|
||||
public byte[] manifest;
|
||||
public String secret;
|
||||
public SubscriberId author;
|
||||
public long rowId;
|
||||
public long insertTime;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
try {
|
||||
if (value!="" && (columnName.equals("manifestid")||columnName.equals("id")))
|
||||
manifestId = new BundleId(value);
|
||||
if (value!="" && columnName.equals("filehash"))
|
||||
fileHash = new FileHash(value);
|
||||
if (value!="" && columnName.equals("BK"))
|
||||
bundleKey = new BundleKey(value);
|
||||
if (value!="" && columnName.equals(".author"))
|
||||
author = new SubscriberId(value);
|
||||
} catch (AbstractId.InvalidHexException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (columnName.equals("service"))
|
||||
service = value;
|
||||
if (columnName.equals("name"))
|
||||
name = value;
|
||||
if (columnName.equals("secret"))
|
||||
secret = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
if (columnName.equals("manifest"))
|
||||
this.manifest = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
if (columnName.equals("version"))
|
||||
version = value;
|
||||
if (columnName.equals("filesize"))
|
||||
fileSize = value;
|
||||
if (columnName.equals("date"))
|
||||
date = value;
|
||||
if (columnName.equals("crypt"))
|
||||
crypt = (int)value;
|
||||
if (columnName.equals(".readonly"))
|
||||
readonly = value>0;
|
||||
if (columnName.equals(".fromhere"))
|
||||
readonly = value==0;
|
||||
if (columnName.equals(".rowid") || columnName.equals("_id"))
|
||||
rowId = value;
|
||||
if (columnName.equals(".inserttime"))
|
||||
insertTime = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static ManifestResult rhizomeAddFile(File payloadPath, File manifestPath, SubscriberId author, String pin)
|
||||
throws ServalDFailureException
|
||||
{
|
||||
|
||||
List<String> args = new LinkedList<String>();
|
||||
args.add("rhizome");
|
||||
args.add("add");
|
||||
args.add("file");
|
||||
if (pin != null) {
|
||||
args.add("--entry-pin");
|
||||
args.add(pin);
|
||||
}
|
||||
args.add(author == null ? "" : author.toHex());
|
||||
if (payloadPath != null)
|
||||
args.add(payloadPath.getAbsolutePath());
|
||||
else if (manifestPath != null)
|
||||
args.add("");
|
||||
if (manifestPath != null)
|
||||
args.add(manifestPath.getAbsolutePath());
|
||||
|
||||
ManifestResult result = new ManifestResult();
|
||||
result.setResult(command(result, args.toArray(new String[args.size()])));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int rhizomeList(AsyncResult<ManifestResult> result, String service, String name, SubscriberId sender, SubscriberId recipient, int offset, int numRows) throws ServalDFailureException {
|
||||
return rhizomeList(new JniResultList<ManifestResult>(result) {
|
||||
@Override
|
||||
public ManifestResult create() {
|
||||
return new ManifestResult();
|
||||
}
|
||||
}, service, name, sender, recipient, offset, numRows);
|
||||
}
|
||||
|
||||
public static int rhizomeList(IJniResults result, String service, String name, SubscriberId sender, SubscriberId recipient, int offset, int numRows) throws ServalDFailureException {
|
||||
List<String> args = new LinkedList<String>();
|
||||
args.add("rhizome");
|
||||
args.add("list");
|
||||
args.add(service == null ? "" : service);
|
||||
args.add(name == null ? "" : name);
|
||||
args.add(sender == null ? "" : sender.toHex());
|
||||
args.add(recipient == null ? "" : recipient.toHex());
|
||||
if (offset > 0)
|
||||
args.add("" + offset);
|
||||
else if (numRows > 0)
|
||||
args.add("0");
|
||||
if (numRows > 0)
|
||||
args.add("" + numRows);
|
||||
return command(result, args.toArray(new String[args.size()]));
|
||||
}
|
||||
|
||||
public static ManifestResult rhizomeImportBundle(File payloadFile,
|
||||
File manifestFile) throws ServalDFailureException {
|
||||
ManifestResult result = new ManifestResult();
|
||||
result.setResult(command(result, "rhizome", "import", "bundle",
|
||||
payloadFile.getAbsolutePath(), manifestFile.getAbsolutePath()));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ManifestResult rhizomeExtractBundle(BundleId manifestId, File manifestFile, File payloadFile) throws ServalDFailureException{
|
||||
ManifestResult result = new ManifestResult();
|
||||
result.setResult(command(result, "rhizome", "extract", "bundle",
|
||||
manifestId.toHex(),
|
||||
manifestFile == null ? "-" : manifestFile.getAbsolutePath(),
|
||||
payloadFile.getAbsolutePath()));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ManifestResult rhizomeExportManifest(BundleId manifestId, File manifestFile) throws ServalDFailureException{
|
||||
ManifestResult result = new ManifestResult();
|
||||
result.setResult(command(result, "rhizome", "export", "manifest",
|
||||
manifestId.toHex(),
|
||||
manifestFile == null ? "-" : manifestFile.getAbsolutePath()));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ManifestResult rhizomeExtractFile(BundleId manifestId, File payloadFile) throws ServalDFailureException{
|
||||
ManifestResult result = new ManifestResult();
|
||||
result.setResult(command(result, "rhizome", "extract", "file",
|
||||
manifestId.toHex(),
|
||||
payloadFile.getAbsolutePath()));
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Common entry point into servald command line.
|
||||
* Push Rhizome bundles to all configured direct hosts.
|
||||
*
|
||||
* @param args
|
||||
* The parameters as passed on the command line, eg: res =
|
||||
* servald.command("config", "set", "debug", "peers");
|
||||
* @return An object containing the servald exit status code (normally0
|
||||
* indicates success) and zero or more output fields that it would
|
||||
* have sent to standard output if invoked via a shell command line.
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
|
||||
public static synchronized ServalDResult command(String... args)
|
||||
throws ServalDInterfaceError
|
||||
public static void rhizomeDirectPush() throws ServalDFailureException
|
||||
{
|
||||
LinkedList<byte[]> results = new LinkedList<byte[]>();
|
||||
int status = rawCommand(new JniResultsList(results), args);
|
||||
return new ServalDResult(args, status, results.toArray(new byte[results.size()][]));
|
||||
command("rhizome", "direct", "push");
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args)
|
||||
/**
|
||||
* Pull Rhizome bundles from all configured direct hosts.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
public static void rhizomeDirectPull() throws ServalDFailureException
|
||||
{
|
||||
LinkedList<byte[]> outv = new LinkedList<byte[]>();
|
||||
IJniResults results = new JniResultsList(outv);
|
||||
int status = rawCommand(results, args);
|
||||
for (byte[] a: outv) {
|
||||
System.out.println(new String(a));
|
||||
command("rhizome", "direct", "pull");
|
||||
}
|
||||
System.exit(status);
|
||||
|
||||
/**
|
||||
* Sync (push and pull) Rhizome bundles from all configured direct hosts.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
public static void rhizomeDirectSync() throws ServalDFailureException
|
||||
{
|
||||
command("rhizome", "direct", "sync");
|
||||
}
|
||||
|
||||
public static class ConfigItems extends JniResult{
|
||||
public Map<String, String> values = new HashMap<String, String>();
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
values.put(this.columnName, value);
|
||||
}
|
||||
}
|
||||
|
||||
public static ConfigItems getConfig(String pattern) throws ServalDFailureException {
|
||||
ConfigItems results = new ConfigItems();
|
||||
results.setResult(command(results, "config", "get", pattern));
|
||||
return results;
|
||||
}
|
||||
|
||||
public static String getConfigItem(String name) throws ServalDFailureException{
|
||||
Object result = getConfig(name).values.get(name);
|
||||
if (result == null)
|
||||
return null;
|
||||
if (result instanceof byte[]){
|
||||
return new String((byte[])result);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static void deleteConfig(String name) throws ServalDFailureException {
|
||||
ServalDCommand.command("config", "del", name);
|
||||
}
|
||||
|
||||
public static void setConfigItem(String name, String value) throws ServalDFailureException {
|
||||
ServalDCommand.command("config", "set", name, value);
|
||||
}
|
||||
|
||||
public static boolean getConfigItemBoolean(String name, boolean defaultValue) {
|
||||
try {
|
||||
String value = getConfigItem(name);
|
||||
return parseBoolean(value, defaultValue);
|
||||
} catch (ServalDFailureException e) {
|
||||
e.printStackTrace();
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getConfigItemInt(String name, int defaultValue) throws ServalDFailureException{
|
||||
try {
|
||||
return Integer.parseInt(getConfig(name).values.get(name));
|
||||
} catch (ServalDFailureException e) {
|
||||
e.printStackTrace();
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PeerCount extends JniResult{
|
||||
long count;
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
count = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int peerCount() throws ServalDFailureException {
|
||||
PeerCount result = new PeerCount();
|
||||
result.setResult(ServalDCommand.command(result, "peer", "count"));
|
||||
return (int)result.count;
|
||||
}
|
||||
|
||||
public static int idPeers(AsyncResult<IdentityResult> results) throws ServalDFailureException {
|
||||
return idPeers(new JniResultList<IdentityResult>(results) {
|
||||
@Override
|
||||
public IdentityResult create() {
|
||||
return new IdentityResult();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static int idPeers(IJniResults results) throws ServalDFailureException {
|
||||
return command(results, "id", "peers");
|
||||
}
|
||||
|
||||
public static class Conversation extends JniResult{
|
||||
public long id;
|
||||
public SubscriberId recipient;
|
||||
public String read;
|
||||
public long last_message;
|
||||
public long read_offset;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
if (columnName.equals("read"))
|
||||
this.read = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
if (columnName.equals("recipient"))
|
||||
try {
|
||||
this.recipient = new SubscriberId(value);
|
||||
} catch (AbstractId.InvalidBinaryException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
if (columnName.equals("_id"))
|
||||
this.id = value;
|
||||
if (columnName.equals("last_message"))
|
||||
this.last_message = value;
|
||||
if (columnName.equals("read_offset"))
|
||||
this.read_offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int listConversations(AsyncResult<Conversation> result, final SubscriberId sender, int offset, int numRows) throws ServalDFailureException {
|
||||
return listConversations(new JniResultList<Conversation>(result) {
|
||||
@Override
|
||||
public Conversation create() {
|
||||
return new Conversation();
|
||||
}
|
||||
}, sender, offset, numRows);
|
||||
}
|
||||
|
||||
public static int listConversations(IJniResults callback, final SubscriberId sender, int offset, int numRows) throws ServalDFailureException {
|
||||
return command(callback, "meshms", "list", "conversations",
|
||||
sender.toHex(), ""+offset, ""+numRows);
|
||||
}
|
||||
|
||||
public static class Message extends JniResult{
|
||||
public long id;
|
||||
public long offset;
|
||||
public String type;
|
||||
public String message;
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
if (columnName.equals("type"))
|
||||
this.type = value;
|
||||
if (columnName.equals("message"))
|
||||
this.message = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
if (columnName.equals("_id"))
|
||||
this.id = value;
|
||||
if (columnName.equals("offset"))
|
||||
this.offset = value;
|
||||
}
|
||||
}
|
||||
|
||||
public static int listMessages(AsyncResult<Message> result, final SubscriberId sender, final SubscriberId recipient) throws ServalDFailureException {
|
||||
return listMessages(new JniResultList<Message>(result) {
|
||||
@Override
|
||||
public Message create() {
|
||||
return new Message();
|
||||
}
|
||||
}, sender, recipient);
|
||||
}
|
||||
|
||||
public static int listMessages(IJniResults callback, final SubscriberId sender, final SubscriberId recipient) throws ServalDFailureException {
|
||||
return ServalDCommand.command(callback, "meshms", "list", "messages",
|
||||
sender.toHex(), recipient.toHex());
|
||||
}
|
||||
|
||||
public static void sendMessage(final SubscriberId sender, final SubscriberId recipient, String message) throws ServalDFailureException {
|
||||
command("meshms", "send", "message",
|
||||
sender.toHex(), recipient.toHex(),
|
||||
message);
|
||||
}
|
||||
|
||||
public static void readMessage(final SubscriberId sender, final SubscriberId recipient) throws ServalDFailureException {
|
||||
command("meshms", "read", "messages",
|
||||
sender.toHex(), recipient.toHex());
|
||||
}
|
||||
|
||||
public static void readMessage(final SubscriberId sender, final SubscriberId recipient, long offset) throws ServalDFailureException {
|
||||
command("meshms", "read", "messages",
|
||||
sender.toHex(), recipient.toHex(),
|
||||
"" + offset);
|
||||
}
|
||||
|
||||
public static int printCommand(final String fieldDelim, final String rowDelim, String... args){
|
||||
return rawCommand(new IJniResults() {
|
||||
int columns =-1;
|
||||
int column =-1;
|
||||
@Override
|
||||
public void startResultSet(int columns) {
|
||||
this.columns=columns;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColumnName(int column, String name) {
|
||||
System.out.print(name + fieldDelim);
|
||||
if (column>=0 && column+1==columns)
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private void eol(){
|
||||
if (columns==-1 || ++column==columns){
|
||||
System.out.print(rowDelim);
|
||||
column=-1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putString(String value) {
|
||||
System.out.print(value);
|
||||
eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putBlob(byte[] value) {
|
||||
System.out.print(new String(value));
|
||||
eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putLong(long value) {
|
||||
System.out.print(value);
|
||||
eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putDouble(double value) {
|
||||
System.out.print(value);
|
||||
eol();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void totalRowCount(int rows) {
|
||||
}
|
||||
}, args);
|
||||
}
|
||||
|
||||
public static void main(String... args)
|
||||
{
|
||||
System.exit(printCommand(":","\n",args));
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,6 @@
|
||||
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import org.servalproject.servaldna.ServalDResult;
|
||||
|
||||
/**
|
||||
* Thrown when a request to a servald JNI method fails. This typically means that the returned
|
||||
* status is non-zero, or some other result was returned that indicated the operation failed.
|
||||
@ -32,10 +30,6 @@ public class ServalDFailureException extends Exception
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public ServalDFailureException(String message, ServalDResult result) {
|
||||
super(message + " for command: " + result.getCommandString());
|
||||
}
|
||||
|
||||
public ServalDFailureException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
@ -1,217 +0,0 @@
|
||||
/**
|
||||
* Copyright (C) 2011 The Serval Project
|
||||
*
|
||||
* This file is part of Serval Software (http://www.servalproject.org)
|
||||
*
|
||||
* Serval Software is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This source code is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this source code; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package org.servalproject.servaldna;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/** Represents the result of invoking servald via the JNI command-line interface. The 'args'
|
||||
* attribute contains a copy of the arguments that were passed to the call that produced this
|
||||
* result, to facilitate diagnosis of failures and errors. The results of a call are an integer
|
||||
* 'status' value (normally the process exit status) and a list of strings in 'outv', called "output
|
||||
* fields". These strings must be interpreted depending on the operation that produced them.
|
||||
*
|
||||
* Many operations return information about their outcome as a sequence of key-value pairs of
|
||||
* fields. The getField() method and variants offer an order-independent means to query these
|
||||
* fields by key and optionally enforce a type on the value. If the operation produces output
|
||||
* that is not in the key-value structure, then the caller simply avoids using these methods,
|
||||
* and accesses the 'outv' array directly.
|
||||
*
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
*/
|
||||
public class ServalDResult
|
||||
{
|
||||
public static final int STATUS_ERROR = 255;
|
||||
|
||||
public final String[] args;
|
||||
public final int status;
|
||||
public final byte[][] outv;
|
||||
private HashMap<String,byte[]> keyValue;
|
||||
|
||||
public ServalDResult(String[] args, int status, byte[][] outv) {
|
||||
this.args = args;
|
||||
this.status = status;
|
||||
this.outv = outv;
|
||||
this.keyValue = null;
|
||||
}
|
||||
|
||||
public ServalDResult(ServalDResult orig) {
|
||||
this.args = orig.args;
|
||||
this.status = orig.status;
|
||||
this.outv = orig.outv;
|
||||
this.keyValue = orig.keyValue;
|
||||
}
|
||||
|
||||
public String getCommandString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < this.args.length; i++) {
|
||||
if (i > 0)
|
||||
sb.append(' ');
|
||||
sb.append(args[i]);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
@Override
|
||||
public String toString() {
|
||||
String[] outvstr = new String[this.outv.length];
|
||||
for (int i = 0; i != this.outv.length; ++i)
|
||||
outvstr[i] = new String(this.outv[i]);
|
||||
return this.getClass().getName() + "(args=" + Arrays.deepToString(this.args) + ", status=" + this.status + ", outv=" + Arrays.deepToString(outvstr) + ")";
|
||||
}
|
||||
|
||||
public void failIfStatusError() throws ServalDFailureException {
|
||||
if (this.status == STATUS_ERROR)
|
||||
throw new ServalDFailureException("error exit status", this);
|
||||
}
|
||||
|
||||
public void failIfStatusNonzero() throws ServalDFailureException {
|
||||
if (this.status != 0)
|
||||
throw new ServalDFailureException("non-zero exit status", this);
|
||||
}
|
||||
|
||||
protected void makeKeyValueMap() {
|
||||
if (this.keyValue == null) {
|
||||
if (this.outv.length % 2 != 0)
|
||||
throw new ServalDInterfaceError("odd number of fields", this);
|
||||
this.keyValue = new HashMap<String,byte[]>();
|
||||
for (int i = 0; i != this.outv.length; i += 2)
|
||||
this.keyValue.put(new String(this.outv[i]), this.outv[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String,byte[]> getKeyValueMap() {
|
||||
makeKeyValueMap();
|
||||
return new HashMap<String,byte[]>(this.keyValue);
|
||||
}
|
||||
|
||||
protected byte[] getFieldOrNull(String fieldName) {
|
||||
makeKeyValueMap();
|
||||
if (!this.keyValue.containsKey(fieldName))
|
||||
return null;
|
||||
return this.keyValue.get(fieldName);
|
||||
}
|
||||
|
||||
protected byte[] getField(String fieldName) throws ServalDInterfaceError {
|
||||
byte[] value = getFieldOrNull(fieldName);
|
||||
if (value == null)
|
||||
throw new ServalDInterfaceError("missing '" + fieldName + "' field", this);
|
||||
return value;
|
||||
}
|
||||
|
||||
public byte[] getFieldByteArray(String fieldName, byte[] defaultValue) {
|
||||
byte[] value = getFieldOrNull(fieldName);
|
||||
if (value == null)
|
||||
return defaultValue;
|
||||
return value;
|
||||
}
|
||||
|
||||
public String getFieldString(String fieldName, String defaultValue) {
|
||||
byte[] value = getFieldOrNull(fieldName);
|
||||
if (value == null)
|
||||
return defaultValue;
|
||||
return new String(value);
|
||||
}
|
||||
|
||||
public String getFieldString(String fieldName) throws ServalDInterfaceError {
|
||||
return new String(getField(fieldName));
|
||||
}
|
||||
|
||||
public String getFieldStringNonEmptyOrNull(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName, "");
|
||||
return value.length() == 0 ? null : value;
|
||||
}
|
||||
|
||||
public long getFieldLong(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName);
|
||||
try {
|
||||
return Long.valueOf(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + value + "' is not of type long", this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public int getFieldInt(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName);
|
||||
try {
|
||||
return Integer.valueOf(value);
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + value + "' is not of type int", this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean getFieldBoolean(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName);
|
||||
try {
|
||||
if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("on"))
|
||||
return true;
|
||||
if (value.equalsIgnoreCase("false") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("off"))
|
||||
return false;
|
||||
return Integer.parseInt(value) != 0;
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + value + "' is not of type boolean", this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public SubscriberId getFieldSubscriberId(String fieldName, SubscriberId defaultValue) throws ServalDInterfaceError {
|
||||
byte[] value = getFieldOrNull(fieldName);
|
||||
if (value == null)
|
||||
return defaultValue;
|
||||
String str = new String(value);
|
||||
try {
|
||||
return new SubscriberId(str);
|
||||
}
|
||||
catch (AbstractId.InvalidHexException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + str + "' is not a Bundle ID: " + e.getMessage(), this);
|
||||
}
|
||||
}
|
||||
|
||||
public SubscriberId getFieldSubscriberId(String fieldName) throws ServalDInterfaceError {
|
||||
SubscriberId value = getFieldSubscriberId(fieldName, null);
|
||||
if (value == null)
|
||||
throw new ServalDInterfaceError("missing '" + fieldName + "' field", this);
|
||||
return value;
|
||||
}
|
||||
|
||||
public BundleId getFieldBundleId(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName);
|
||||
try {
|
||||
return new BundleId(value);
|
||||
}
|
||||
catch (BundleId.InvalidHexException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + value + "' is not a Bundle ID: " + e.getMessage(), this, e);
|
||||
}
|
||||
}
|
||||
|
||||
public FileHash getFieldFileHash(String fieldName) throws ServalDInterfaceError {
|
||||
String value = getFieldString(fieldName);
|
||||
try {
|
||||
return new FileHash(value);
|
||||
}
|
||||
catch (BundleId.InvalidHexException e) {
|
||||
throw new ServalDInterfaceError("field " + fieldName + "='" + value + "' is not a file hash: " + e.getMessage(), this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -59,6 +59,7 @@ public class SubscriberId extends AbstractId {
|
||||
}
|
||||
|
||||
public static SubscriberId broadcastSid;
|
||||
public static SubscriberId ANY;
|
||||
static {
|
||||
byte buff[] = new byte[BINARY_SIZE];
|
||||
for (int i = 0; i < BINARY_SIZE; i++)
|
||||
@ -68,5 +69,14 @@ public class SubscriberId extends AbstractId {
|
||||
} catch (InvalidBinaryException e) {
|
||||
// TODO log error?
|
||||
}
|
||||
|
||||
buff = new byte[BINARY_SIZE];
|
||||
for (int i = 0; i < BINARY_SIZE; i++)
|
||||
buff[i] = (byte) 0x00;
|
||||
try {
|
||||
ANY = new SubscriberId(buff);
|
||||
} catch (InvalidBinaryException e) {
|
||||
// TODO log error?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +1,12 @@
|
||||
package org.servalproject.test;
|
||||
|
||||
import org.servalproject.servaldna.ServalDCommand;
|
||||
import org.servalproject.servaldna.ServalDResult;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
class ServalDTests
|
||||
{
|
||||
public static void main(String[] args)
|
||||
public static void main(String... args)
|
||||
{
|
||||
try {
|
||||
for (int i = 0; i != args.length; ++i)
|
||||
@ -22,14 +21,8 @@ class ServalDTests
|
||||
}
|
||||
|
||||
while(repeatCount>0){
|
||||
ServalDResult result = ServalDCommand.command(args);
|
||||
System.out.print(result.status);
|
||||
for (byte[] a: result.outv) {
|
||||
System.out.print(":");
|
||||
System.out.print(new String(a));
|
||||
}
|
||||
System.out.println("");
|
||||
|
||||
ServalDCommand.printCommand(""," ",args);
|
||||
System.out.println();
|
||||
repeatCount--;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
SERVAL_SOURCES = \
|
||||
$(SERVAL_BASE)sqlite-amalgamation-3070900/sqlite3.c \
|
||||
$(SERVAL_BASE)cli.c \
|
||||
$(SERVAL_BASE)commandline.c \
|
||||
$(SERVAL_BASE)conf.c \
|
||||
@ -70,7 +71,6 @@ SERVAL_SOURCES = \
|
||||
$(SERVAL_BASE)sha2.c \
|
||||
$(SERVAL_BASE)sighandlers.c \
|
||||
$(SERVAL_BASE)slip.c \
|
||||
$(SERVAL_BASE)sqlite-amalgamation-3070900/sqlite3.c \
|
||||
$(SERVAL_BASE)srandomdev.c \
|
||||
$(SERVAL_BASE)str.c \
|
||||
$(SERVAL_BASE)strbuf.c \
|
||||
|
52
testdefs.sh
52
testdefs.sh
@ -78,6 +78,57 @@ extract_stdout_keyvalue() {
|
||||
assert --message="stdout of ($executed) contains valid '$_label:' line" --stdout extract_stdout_keyvalue_optional "$@"
|
||||
}
|
||||
|
||||
# Parse the standard result set output produced by the immediately preceding command
|
||||
# command into the following shell variables:
|
||||
# NCOLS the number of columns
|
||||
# NROWS the number of data rows (not counting headers)
|
||||
# HEADER[c] the C-th header label, 0 <= C <= NCOLS-1
|
||||
# <label>[R] where <label> is a header label with all non-alphanumerics
|
||||
# replaced by underscore '_' and all alphas converted to upper case, eg,
|
||||
# .author -> _AUTHOR, is the value of that column in the R-th row, 0 <=
|
||||
# R < NROWS
|
||||
#
|
||||
# Warning: overwrites existing shell variables. Names of overwritten shell
|
||||
# variables are derived directly from the output of the command, so cannot be
|
||||
# controlled. If a prefix is supplied, all variables are prefixed with that.
|
||||
unpack_stdout_list() {
|
||||
local prefix="$1"
|
||||
{
|
||||
local n
|
||||
read n
|
||||
eval ${prefix}NCOLS=\"\$n\"
|
||||
declare -a ${prefix}HEADER
|
||||
local -a header
|
||||
local oIFS="$IFS"
|
||||
IFS=:
|
||||
read -r -a header
|
||||
IFS="$oIFS"
|
||||
eval ${prefix}HEADER="(\"\${header[@]}\")"
|
||||
local hdr
|
||||
local -a colvars=()
|
||||
for hdr in "${header[@]}"; do
|
||||
hdr="${hdr//[^A-Za-z0-9_]/_}"
|
||||
# hdr="${hdr^^*}" would do in Bash-4.0 and later
|
||||
hdr="$(echo "$hdr" | sed -e 's/.*/\U&/')"
|
||||
colvars+=("$hdr")
|
||||
done
|
||||
local -a row
|
||||
IFS=:
|
||||
local i=0
|
||||
while eval read -r -a row; do
|
||||
local j=0
|
||||
local val
|
||||
for val in "${row[@]}"; do
|
||||
eval ${prefix}${colvars[$j]}[$i]=\"\$val\"
|
||||
let ++j
|
||||
done
|
||||
let ++i
|
||||
done
|
||||
IFS="$oIFS"
|
||||
eval ${prefix}NROWS=$i
|
||||
} < <(replayStdout)
|
||||
}
|
||||
|
||||
# Utility function for creating servald fixtures:
|
||||
# - set $servald variable (executable under test)
|
||||
# - set the current instance to be "Z"
|
||||
@ -641,7 +692,6 @@ create_identities() {
|
||||
done
|
||||
done
|
||||
executeOk_servald keyring list "${servald_options[@]}"
|
||||
assertStdoutLineCount '==' $N
|
||||
for ((i = 1; i <= N; ++i)); do
|
||||
local sidvar=SID$instance_name$i
|
||||
local didvar=DID$instance_name$i
|
||||
|
@ -78,63 +78,6 @@ assert_rhizome_list() {
|
||||
rhizome_list_file_count=$(( $(replayStdout | wc -l) - 2 ))
|
||||
}
|
||||
|
||||
# Parse the standard output produced by the immediately preceding "rhizome list"
|
||||
# command into the following shell variables:
|
||||
# NCOLS the number of columns
|
||||
# NROWS the number of data rows (not counting headers)
|
||||
# HEADER[c] the C-th header label, 0 <= C <= NCOLS-1
|
||||
# <label>[R] where <label> is a header label with all non-alphanumerics
|
||||
# replaced by underscore '_' and all alphas converted to upper case, eg,
|
||||
# .author -> _AUTHOR, is the value of that column in the R-th row, 0 <=
|
||||
# R < NROWS
|
||||
#
|
||||
# Warning: overwrites existing shell variables. Names of overwritten shell
|
||||
# variables are derived directly from the output of rhizome list, so cannot be
|
||||
# controlled. If a prefix is supplied, all variables are prefixed with that.
|
||||
rhizome_list_unpack() {
|
||||
local prefix="$1"
|
||||
{
|
||||
local n
|
||||
read n
|
||||
eval ${prefix}NCOLS=\"\$n\"
|
||||
declare -a ${prefix}HEADER
|
||||
local -a header
|
||||
local oIFS="$IFS"
|
||||
IFS=:
|
||||
read -r -a header
|
||||
IFS="$oIFS"
|
||||
eval ${prefix}HEADER="(\"\${header[@]}\")"
|
||||
local hdr
|
||||
local -a colvars=()
|
||||
for hdr in "${header[@]}"; do
|
||||
case "$hdr" in
|
||||
id)
|
||||
hdr=BID;;
|
||||
*)
|
||||
hdr="${hdr//[^A-Za-z0-9_]/_}"
|
||||
# hdr="${hdr^^*}" would do in Bash-4.0 and later
|
||||
hdr="$(echo "$hdr" | sed -e 's/.*/\U&/')"
|
||||
;;
|
||||
esac
|
||||
colvars+=("$hdr")
|
||||
done
|
||||
local -a row
|
||||
IFS=:
|
||||
local i=0
|
||||
while eval read -r -a row; do
|
||||
local j=0
|
||||
local val
|
||||
for val in "${row[@]}"; do
|
||||
eval ${prefix}${colvars[$j]}[$i]=\"\$val\"
|
||||
let ++j
|
||||
done
|
||||
let ++i
|
||||
done
|
||||
IFS="$oIFS"
|
||||
eval ${prefix}NROWS=$i
|
||||
} < "$TFWSTDOUT"
|
||||
}
|
||||
|
||||
rhizome_list_dump() {
|
||||
local ncols
|
||||
local -a headers
|
||||
|
@ -80,10 +80,10 @@ test_publish() {
|
||||
stop_servald_server +D
|
||||
set_instance +A
|
||||
executeOk_servald dna lookup "$DIDB"
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDB/local/$DIDB:$DIDB:$NAMEB\$"
|
||||
executeOk_servald dna lookup "$DIDC"
|
||||
assertStdoutLineCount '==' 2
|
||||
assertStdoutLineCount '==' 4
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDC/local/$DIDC:$DIDC:$NAMEC\$"
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDD/local/$DIDD:$DIDD:$NAMED\$"
|
||||
assert_status_all_servald_servers running
|
||||
@ -147,13 +147,13 @@ test_routing() {
|
||||
executeOk_servald route print
|
||||
assertStdoutGrep --matches=1 "^$SIDA:UNICAST:"
|
||||
executeOk_servald dna lookup "$DIDC"
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDC/local/$DIDC:$DIDC:$NAMEC\$"
|
||||
set_instance +C
|
||||
executeOk_servald route print
|
||||
assertStdoutGrep --matches=1 "^$SIDA:UNICAST:"
|
||||
executeOk_servald dna lookup "$DIDB"
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDB/local/$DIDB:$DIDB:$NAMEB\$"
|
||||
executeOk_servald mdp ping $SIDB 3
|
||||
tfw_cat --stdout --stderr
|
||||
|
@ -258,150 +258,157 @@ EOF
|
||||
}
|
||||
test_ExecArgs() {
|
||||
executeOk_servald dna lookup 12345
|
||||
assertStdoutIs -e "uri:dumb:12345:Hello, World!\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^uri:dumb:12345:Hello, World!\$"
|
||||
}
|
||||
|
||||
doc_ReplyOk1="DNA helper returns one valid reply"
|
||||
test_ReplyOk1() {
|
||||
executeOk_servald dna lookup 00001
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\$"
|
||||
}
|
||||
|
||||
doc_ReplyOk2="DNA helper returns two valid replies"
|
||||
test_ReplyOk2() {
|
||||
executeOk_servald dna lookup 00002
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00002:Joe A. Bloggs\nsip://$SID_JOE_B@10.1.1.1:00002:Joe B. Bloggs\n"
|
||||
assertStdoutLineCount '==' 4
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00002:Joe A. Bloggs\$"
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_B@10.1.1.1:00002:Joe B. Bloggs\$"
|
||||
}
|
||||
|
||||
doc_ReplyOk3="DNA helper returns three valid replies"
|
||||
test_ReplyOk3() {
|
||||
executeOk_servald dna lookup 00003
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00003:Joe A. Bloggs\nsip://$SID_JOE_B@10.1.1.1:00003:Joe B. Bloggs\nsip://$SID_JOE_C@10.1.1.1:00003:Joe C. Bloggs\n"
|
||||
assertStdoutLineCount '==' 5
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00003:Joe A. Bloggs\$"
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_B@10.1.1.1:00003:Joe B. Bloggs\$"
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_C@10.1.1.1:00003:Joe C. Bloggs\$"
|
||||
}
|
||||
|
||||
doc_UriEmpty="DNA helper returns empty URI"
|
||||
test_UriEmpty() {
|
||||
executeOk_servald dna lookup 00004
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*empty URI'
|
||||
}
|
||||
|
||||
doc_UriInvalid1="DNA helper returns invalid URI, missing scheme"
|
||||
test_UriInvalid1() {
|
||||
executeOk_servald dna lookup 000051
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*Bluebottle.*invalid URI'
|
||||
}
|
||||
|
||||
doc_UriInvalid2="DNA helper returns invalid URI, invalid char"
|
||||
test_UriInvalid2() {
|
||||
executeOk_servald dna lookup 000052
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*sip://Sea goon.*invalid URI'
|
||||
}
|
||||
|
||||
doc_UriInvalid3="DNA helper returns invalid URI, empty hierarchical part"
|
||||
test_UriInvalid3() {
|
||||
executeOk_servald dna lookup 000053
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*sip:.*invalid URI'
|
||||
}
|
||||
|
||||
doc_TokenMismatch="DNA helper returns mismatched token"
|
||||
test_TokenMismatch() {
|
||||
executeOk_servald dna lookup 000061
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*mismatched token'
|
||||
}
|
||||
|
||||
doc_TokenEmpty="DNA helper returns empty token"
|
||||
test_TokenEmpty() {
|
||||
executeOk_servald dna lookup 000062
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*empty token'
|
||||
}
|
||||
|
||||
doc_TokenInvalid="DNA helper returns invalid token"
|
||||
test_TokenInvalid() {
|
||||
executeOk_servald dna lookup 000063
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*invalid token'
|
||||
}
|
||||
|
||||
doc_TokenInvalidLong="DNA helper returns invalid token, too long"
|
||||
test_TokenInvalidLong() {
|
||||
executeOk_servald dna lookup 000064
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply.*invalid'
|
||||
}
|
||||
|
||||
doc_TokenInvalidShort="DNA helper returns invalid token, too short"
|
||||
test_TokenInvalidShort() {
|
||||
executeOk_servald dna lookup 000065
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*invalid token'
|
||||
}
|
||||
|
||||
doc_DidMismatch="DNA helper returns mismatched DID"
|
||||
test_DidMismatch() {
|
||||
executeOk_servald dna lookup 000071
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*mismatched DID'
|
||||
}
|
||||
|
||||
doc_DidEmpty="DNA helper returns empty DID"
|
||||
test_DidEmpty() {
|
||||
executeOk_servald dna lookup 000072
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*empty DID'
|
||||
}
|
||||
|
||||
doc_DidInvalid="DNA helper returns invalid DID"
|
||||
test_DidInvalid() {
|
||||
executeOk_servald dna lookup 000073
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*invalid DID'
|
||||
}
|
||||
|
||||
doc_DidInvalidLong="DNA helper returns invalid DID, too long"
|
||||
test_DidInvalidLong() {
|
||||
executeOk_servald dna lookup 000074
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply.*invalid'
|
||||
}
|
||||
|
||||
doc_DidInvalidShort="DNA helper returns invalid DID, too short"
|
||||
test_DidInvalidShort() {
|
||||
executeOk_servald dna lookup 000075
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*invalid DID'
|
||||
}
|
||||
|
||||
doc_ReplyInvalidMissingDelim="DNA helper returns invalid reply, missing delimiter"
|
||||
test_ReplyInvalidMissingDelim() {
|
||||
executeOk_servald dna lookup 000081
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply.*invalid'
|
||||
}
|
||||
|
||||
doc_ReplyInvalidLongName="DNA helper returns invalid reply, name too long"
|
||||
test_ReplyInvalidLongName() {
|
||||
executeOk_servald dna lookup 000082
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply.*invalid'
|
||||
}
|
||||
|
||||
doc_ReplyInvalidEmpty="DNA helper returns invalid reply, empty line"
|
||||
test_ReplyInvalidEmpty() {
|
||||
executeOk_servald dna lookup 000083
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply .\\n. invalid'
|
||||
}
|
||||
|
||||
doc_ReplyInvalidMissingNewline="DNA helper returns invalid reply, missing newline"
|
||||
test_ReplyInvalidMissingNewline() {
|
||||
executeOk_servald dna lookup 000084
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply.*spurious'
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply timeout'
|
||||
}
|
||||
@ -409,30 +416,34 @@ test_ReplyInvalidMissingNewline() {
|
||||
doc_HelperTimeout="DNA helper process takes too long to reply and is restarted"
|
||||
test_HelperTimeout() {
|
||||
executeOk_servald dna lookup 00009
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*reply timeout'
|
||||
assertGrep "$LOGA" 'INFO:.*DNAHELPER.*process.*terminated by signal 15'
|
||||
executeOk_servald dna lookup 00001
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\$"
|
||||
}
|
||||
|
||||
doc_ReplySpurious="DNA helper spurious output after DONE is ignored"
|
||||
test_ReplySpurious() {
|
||||
executeOk_servald dna lookup 00010
|
||||
assertStdoutIs -e "sip://$SID_JOE_E@10.1.1.1:00010:Joe E. Bloggs\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_E@10.1.1.1:00010:Joe E. Bloggs\$"
|
||||
assertGrep "$LOGA" 'WARN:.*DNAHELPER.*spurious output'
|
||||
executeOk_servald dna lookup 00001
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\$"
|
||||
}
|
||||
|
||||
doc_HelperDies="DNA helper process dies unexpectedly and is restarted"
|
||||
test_HelperDies() {
|
||||
executeOk_servald dna lookup 00011
|
||||
assertStdoutIs ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertGrep "$LOGA" 'INFO:.*DNAHELPER.*process.*exited normally with status 42'
|
||||
assertGrep "$LOGA" 'ERROR:.*DNAHELPER.*goodbye cruel world\\n'
|
||||
executeOk_servald dna lookup 00001
|
||||
assertStdoutIs -e "sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\n"
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --stdout --matches=1 "^sip://$SID_JOE_A@10.1.1.1:00001:Joe A. Bloggs\$"
|
||||
}
|
||||
|
||||
runTests "$@"
|
||||
|
@ -54,7 +54,7 @@ set_server_vars() {
|
||||
doc_LookupWildcard="Lookup by wildcard"
|
||||
test_LookupWildcard() {
|
||||
executeOk_servald dna lookup "*"
|
||||
assertStdoutLineCount '==' 2
|
||||
assertStdoutLineCount '==' 4
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDA/local/$DIDA:$DIDA:$NAMEA\$"
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDB/local/$DIDB:$DIDB:$NAMEB\$"
|
||||
}
|
||||
@ -62,7 +62,7 @@ test_LookupWildcard() {
|
||||
doc_LookupEmpty="Lookup by empty string"
|
||||
test_LookupEmpty() {
|
||||
executeOk_servald dna lookup ""
|
||||
assertStdoutLineCount '==' 2
|
||||
assertStdoutLineCount '==' 4
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDA/local/$DIDA:$DIDA:$NAMEA\$"
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDB/local/$DIDB:$DIDB:$NAMEB\$"
|
||||
}
|
||||
@ -70,20 +70,20 @@ test_LookupEmpty() {
|
||||
doc_LookupNonExistent="Lookup non-existent phone number"
|
||||
test_LookupNonExistent() {
|
||||
executeOk_servald dna lookup "5551234"
|
||||
assertStdoutLineCount '==' 0
|
||||
assertStdoutLineCount '==' 2
|
||||
}
|
||||
|
||||
doc_LookupLocal="Lookup local phone number"
|
||||
test_LookupLocal() {
|
||||
executeOk_servald dna lookup "$DIDA"
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDA/local/$DIDA:$DIDA:$NAMEA\$"
|
||||
}
|
||||
|
||||
doc_LookupRemote="Lookup remote phone number"
|
||||
test_LookupRemote() {
|
||||
executeOk_servald dna lookup "$DIDB"
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "^sid://$SIDB/local/$DIDB:$DIDB:$NAMEB\$"
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ setup_MultiLookupHelperThree() {
|
||||
}
|
||||
test_MultiLookupHelperThree() {
|
||||
executeOk_servald dna lookup 00003
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutLineCount '==' 5
|
||||
assertStdoutGrep --matches=1 "uri:A1:00003:Name One$"
|
||||
assertStdoutGrep --matches=1 "uri:B1:00003:Name Three$"
|
||||
assertStdoutGrep --matches=1 "uri:C1:00003:Name Six$"
|
||||
@ -147,7 +147,7 @@ setup_MultiLookupHelperTwo() {
|
||||
}
|
||||
test_MultiLookupHelperTwo() {
|
||||
executeOk_servald dna lookup 00002
|
||||
assertStdoutLineCount '==' 2
|
||||
assertStdoutLineCount '==' 4
|
||||
assertStdoutGrep --matches=1 "uri:A2:00002:Name Two\$"
|
||||
assertStdoutGrep --matches=1 "uri:B2:00002:Name Four\$"
|
||||
}
|
||||
@ -158,7 +158,7 @@ setup_MultiLookupHelperOne() {
|
||||
}
|
||||
test_MultiLookupHelperOne() {
|
||||
executeOk_servald dna lookup 00001
|
||||
assertStdoutLineCount '==' 1
|
||||
assertStdoutLineCount '==' 3
|
||||
assertStdoutGrep --matches=1 "uri:B3:00001:Name Five\$"
|
||||
}
|
||||
|
||||
|
@ -68,7 +68,7 @@ doc_Repeat="Serval JNI repeated calls in same process"
|
||||
test_Repeat() {
|
||||
executeOk --core-backtrace java "-Djava.library.path=$LD_LIBRARY_PATH" -classpath "$PWD/classes" org.servalproject.test.ServalDTests repeat 50 'echo' 'Hello,' 'world!'
|
||||
assertStdoutLineCount '==' 50
|
||||
assertStdoutGrep --matches=50 '^0:Hello,:world!$'
|
||||
assertStdoutGrep --matches=50 '^Hello, world! $'
|
||||
}
|
||||
|
||||
doc_NullArg="Serval JNI null arguments throw exception"
|
||||
|
@ -47,7 +47,8 @@ setup_instances() {
|
||||
}
|
||||
|
||||
assert_keyring_list() {
|
||||
assertStdoutLineCount --stdout --stderr '==' $1
|
||||
unpack_stdout_list X
|
||||
assert --stdout --stderr [ $XNROWS -eq $1 ]
|
||||
assertStdoutGrep --stderr --matches=$1 "^[0-9a-fA-F]\{64\}:[0-9*#+]*:.*\$"
|
||||
tfw_cat --stdout
|
||||
}
|
||||
@ -198,8 +199,9 @@ setup_KeyringPinServer() {
|
||||
test_KeyringPinServer() {
|
||||
start_servald_server --keyring-pin=yellow
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 1
|
||||
assertStdoutGrep --fixed-strings "$SIDA"
|
||||
unpack_stdout_list X
|
||||
assert --stdout --stderr [ $XNROWS -eq 1 ]
|
||||
assert --stdout --stderr [ ${XSID[0]} = $SIDA ]
|
||||
}
|
||||
finally_KeyringPinServer() {
|
||||
stop_servald_server
|
||||
@ -216,8 +218,9 @@ setup_EntryPinServer() {
|
||||
test_EntryPinServer() {
|
||||
start_servald_server --entry-pin=yodel
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 1
|
||||
assertStdoutGrep --fixed-strings "$SIDA"
|
||||
unpack_stdout_list X
|
||||
assert --stdout --stderr [ $XNROWS -eq 1 ]
|
||||
assert --stdout --stderr [ ${XSID[0]} = $SIDA ]
|
||||
}
|
||||
finally_EntryPinServer() {
|
||||
stop_servald_server
|
||||
@ -234,8 +237,9 @@ setup_KeyringEntryPinServer() {
|
||||
test_KeyringEntryPinServer() {
|
||||
start_servald_server --keyring-pin=yellow --entry-pin=yodel
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 1
|
||||
assertStdoutGrep --fixed-strings "$SIDA"
|
||||
unpack_stdout_list X
|
||||
assert --stdout --stderr [ $XNROWS -eq 1 ]
|
||||
assert --stdout --stderr [ ${XSID[0]} = $SIDA ]
|
||||
}
|
||||
finally_KeyringKeyringPinServer() {
|
||||
stop_servald_server
|
||||
@ -259,32 +263,32 @@ setup_KeyringEntryPinServer() {
|
||||
}
|
||||
test_KeyringEntryPinServer() {
|
||||
executeOk_servald id self
|
||||
assertStdoutLineCount == 1
|
||||
assertStdoutGrep --fixed-strings "$SIDA"
|
||||
assertStdoutLineCount == 3
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$SIDA"
|
||||
executeOk_servald id enter pin 'one'
|
||||
executeOk_servald id list
|
||||
assertStdoutLineCount == 2
|
||||
assertStdoutGrep --fixed-strings "sid:$SIDA"
|
||||
assertStdoutGrep --fixed-strings "sid:$ONE"
|
||||
assertStdoutLineCount == 4
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$SIDA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$ONE"
|
||||
executeOk_servald id enter pin 'two'
|
||||
executeOk_servald id list
|
||||
assertStdoutLineCount == 4
|
||||
assertStdoutGrep --fixed-strings "sid:$SIDA"
|
||||
assertStdoutGrep --fixed-strings "sid:$ONE"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWOA"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWOB"
|
||||
assertStdoutLineCount == 6
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$SIDA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$ONE"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$TWOA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$TWOB"
|
||||
executeOk_servald id relinquish pin 'one'
|
||||
executeOk_servald id list
|
||||
assertStdoutLineCount == 3
|
||||
assertStdoutGrep --fixed-strings "sid:$SIDA"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWOA"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWOB"
|
||||
assertStdoutLineCount == 5
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$SIDA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$TWOA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$TWOB"
|
||||
executeOk_servald id relinquish sid "$TWOB"
|
||||
tfw_cat --stderr
|
||||
executeOk_servald id list
|
||||
assertStdoutLineCount == 2
|
||||
assertStdoutGrep --fixed-strings "sid:$SIDA"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWOA"
|
||||
assertStdoutLineCount == 4
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$SIDA"
|
||||
assertStdoutGrep --matches=1 --fixed-strings "$TWOA"
|
||||
}
|
||||
teardown_KeyringEntryPinServer() {
|
||||
teardown_servald
|
||||
@ -306,17 +310,17 @@ setup_ListTags() {
|
||||
}
|
||||
test_ListTags() {
|
||||
executeOk_servald id list
|
||||
assertStdoutLineCount == 3
|
||||
assertStdoutGrep --fixed-strings "sid:$ONE"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWO"
|
||||
assertStdoutGrep --fixed-strings "sid:$THREE"
|
||||
assertStdoutLineCount == 5
|
||||
assertStdoutGrep --fixed-strings "$ONE"
|
||||
assertStdoutGrep --fixed-strings "$TWO"
|
||||
assertStdoutGrep --fixed-strings "$THREE"
|
||||
executeOk_servald id list 'tag1'
|
||||
assertStdoutLineCount == 2
|
||||
assertStdoutGrep --fixed-strings "sid:$ONE"
|
||||
assertStdoutGrep --fixed-strings "sid:$TWO"
|
||||
assertStdoutLineCount == 4
|
||||
assertStdoutGrep --fixed-strings "$ONE"
|
||||
assertStdoutGrep --fixed-strings "$TWO"
|
||||
executeOk_servald id list 'tag1' 'First Value'
|
||||
assertStdoutLineCount == 1
|
||||
assertStdoutGrep --fixed-strings "sid:$ONE"
|
||||
assertStdoutLineCount == 3
|
||||
assertStdoutGrep --fixed-strings "$ONE"
|
||||
}
|
||||
teardown_ListTags() {
|
||||
teardown_servald
|
||||
|
@ -100,17 +100,17 @@ check_meshms_bundles() {
|
||||
# Dump the MeshMS bundles to the log and check consistency
|
||||
# The only "file" bundle should be the conversation list
|
||||
executeOk_servald rhizome list file
|
||||
rhizome_list_unpack X
|
||||
unpack_stdout_list X
|
||||
assert --stdout --stderr [ $XNROWS -eq 1 ]
|
||||
assert --stdout --stderr [ ${XBID[0]} = $CONV_BID ]
|
||||
assert --stdout --stderr [ ${XID[0]} = $CONV_BID ]
|
||||
executeOk_servald rhizome extract bundle $CONV_BID manifest.conv payload.conv $CONV_SECRET
|
||||
tfw_cat -v manifest.conv --hexdump payload.conv
|
||||
# The only "MeshMS2" bundles should be the two ply bundles
|
||||
executeOk_servald rhizome list MeshMS2
|
||||
rhizome_list_unpack X
|
||||
unpack_stdout_list X
|
||||
assert --stdout [ $XNROWS -eq 2 ]
|
||||
local bid
|
||||
for bid in ${XBID[*]}; do
|
||||
for bid in ${XID[*]}; do
|
||||
executeOk_servald rhizome extract bundle $bid manifest.$bid payload.$bid
|
||||
tfw_cat -v manifest.$bid --hexdump payload.$bid
|
||||
done
|
||||
|
Loading…
Reference in New Issue
Block a user