Commit 6e9936f3 authored by Josh Kunz's avatar Josh Kunz

Add unit test for annotated node reset

parent a96a29fe
......@@ -16,7 +16,7 @@ static unsigned int tests_run = 0;
#define _stringify(x) #x
#define stringify(x) _stringify(x)
#define debug(fmt, ...) printf( "line " stringify(__LINE__) ": " fmt, ## __VA_ARGS__)
#define debug(fmt, ...) printf( "line " stringify(__LINE__) ": " fmt "\n", ## __VA_ARGS__)
static int __cn_dispatch_result_new(cn_dispatch_result_t **result) {
if (cn_dispatch_result_alloc(result) != 0) {
......@@ -29,6 +29,7 @@ static int __cn_dispatch_result_new(cn_dispatch_result_t **result) {
static char * __cn_dispatch_result_get_cptr_result(cn_dispatch_result_t *result,
cn_objtype_t type, cptr_t *cptr) {
debug("STATUS: %s", result->msg);
mu_assert("dispatch succeeded", result->status== true);
mu_assert("One cptr item returned", g_list_length(result->items) == 1);
......@@ -36,7 +37,7 @@ static char * __cn_dispatch_result_get_cptr_result(cn_dispatch_result_t *result,
cn_dispatch_result_item_t * item = g_list_nth(result->items, 0)->data;
mu_assert("dispatch result item is cptr", item->type == CN_RESULT_ITEM_CPTR);
debug("cptr should be: %s, is %s\n", cn_objtype_name(type), cn_objtype_name(item->cptr.type));
debug("cptr should be: %s, is %s", cn_objtype_name(type), cn_objtype_name(item->cptr.type));
mu_assert("cptr is appropriate type", item->cptr.type == type);
*cptr = item->cptr.cptr;
......@@ -45,19 +46,20 @@ static char * __cn_dispatch_result_get_cptr_result(cn_dispatch_result_t *result,
}
static char * __cn_dispatch_result_empty(cn_dispatch_result_t * result) {
mu_assert("dispatch succeeded", result->status== true);
debug("STATUS: %s", result->msg);
mu_assert("dispatch succeeded", result->status == true);
mu_assert("no items returned", result->items == NULL);
return NULL;
}
static char * __cn_dispatch_create_single(cn_principal_t *p, cn_objtype_t type, cptr_t *cptr) {
static char * __cn_dispatch_create_single(cn_principal_t *p, cn_objtype_t type, cptr_t *cptr, void * args) {
cn_dispatch_result_t * result;
if (__cn_dispatch_result_new(&result) != 0) {
return "Failed to allocate dispatch result";
}
if (cn_dispatch_create(p, result, type, NULL) != 0) {
if (cn_dispatch_create(p, result, type, args) != 0) {
return "Failed dispatch create";
}
......@@ -69,28 +71,72 @@ static char * __cn_dispatch_create_single(cn_principal_t *p, cn_objtype_t type,
return NULL;
}
static char * test_membrane_membrane_grant(void) {
/* Testing helpers */
cn_principal_t * pa;
static char * __test_can_deref(cn_principal_t *p, cptr_t c) {
struct cnode *cnode;
char * res = NULL;
cn_dispatch_result_t * result = NULL;
if (cn_principal_get(p, c, &cnode) != 0) {
return "Could not deref cptr";
}
/* Create the principal */
cap_cnode_put(cnode);
debug("creating principal\n");
if (cn_principal_new(&pa) != 0) {
return "Failed to allocate pa";
return NULL;
}
static char * __test_can_not_deref(cn_principal_t *p, cptr_t c) {
struct cnode *cnode;
if (cn_principal_get(p, c, &cnode) == 0) {
return "Derefed cptr when it should not be possible";
}
RHOLD_OBJ(pa, dummy_owner);
return NULL;
}
/* Create the internal membrane */
static char * __test_wrapped_by(cn_principal_t *p, cptr_t obj, cptr_t membrane, struct cnode ** cnode_o) {
struct cnode * cnode;
cptr_t pa_membrane_internal;
if (cn_principal_get(p, obj, &cnode) != 0) {
return "Failed to get supposedly wrapped object";
}
cn_cnode_meta_t * meta = cap_cnode_metadata(cnode);
mu_assert("OBJ wrapped cnode should have meta", meta != NULL);
char * meta_s = cn_cnode_meta_string(meta);
debug("OBJ meta: %s", meta_s);
free(meta_s);
mu_assert("OBJ should be wrapped", cn_cnode_is_annotated(cnode));
debug("create membrane internal\n");
res = __cn_dispatch_create_single(pa, CN_MEMBRANE, &pa_membrane_internal);
struct cnode * membrane_cnode;
if (cn_principal_get(p, membrane, &membrane_cnode) != 0) {
return "Couldn't get membrane from principal";
}
mu_assert("Membrane cnode is membrane type", cn_cnode_type(membrane_cnode) == CN_MEMBRANE);
cn_obj_t * membrane_obj = cn_cnode_object(membrane_cnode);
mu_assert("OBJ annotated by membrane", cn_cnode_meta_is_annotated_by(meta, membrane_obj));
cap_cnode_put(membrane_cnode);
*cnode_o = cnode;
return NULL;
}
static char * __cn_obj_wrap(cn_principal_t *p, cptr_t obj, cn_objtype_t obj_type,
cptr_t *mem_in, cptr_t *mem_out, cptr_t *wrapped_o) {
char * res = NULL;
cn_dispatch_result_t * result;
cptr_t membrane_internal;
debug("create membrane internal");
res = __cn_dispatch_create_single(p, CN_MEMBRANE, &membrane_internal, NULL);
if (res != NULL) { return res; }
/* Create the external membrane from the internal membrane */
......@@ -99,37 +145,28 @@ static char * test_membrane_membrane_grant(void) {
return "Failed to allocate dispatch result";
}
debug("create membrane external\n");
if (cn_dispatch_invoke(pa, result, pa_membrane_internal, CN_MEMBRANE_EXTERNAL, NULL) != 0) {
debug("create membrane external");
if (cn_dispatch_invoke(p, result, membrane_internal, CN_MEMBRANE_EXTERNAL, NULL) != 0) {
return "Failed dispatch invoke external on membrane";
}
cptr_t pa_membrane_external;
cptr_t membrane_external;
res = __cn_dispatch_result_get_cptr_result(result, CN_MEMBRANE, &pa_membrane_external);
res = __cn_dispatch_result_get_cptr_result(result, CN_MEMBRANE, &membrane_external);
if (res != NULL) { return res; }
cn_dispatch_result_free(result);
/* Create a dummy object to send through the membrane */
debug("create test rp\n");
cptr_t rp;
res = __cn_dispatch_create_single(pa, CN_RP, &rp);
if (res != NULL) { return res; }
/* Send the dummy object through the membrane */
cn_dispatch_invoke_membrane_send_args_t membrane_send_args = {
.cap = rp,
.cap = obj,
};
if (__cn_dispatch_result_new(&result) != 0) {
return "Failed to allocate dispatch result";
}
debug("do membrane send\n");
if (cn_dispatch_invoke(pa, result, pa_membrane_internal,
debug("do membrane send");
if (cn_dispatch_invoke(p, result, membrane_internal,
CN_MEMBRANE_SEND, (void *) &membrane_send_args) != 0) {
return "Sending on the membrane failed";
}
......@@ -145,23 +182,60 @@ static char * test_membrane_membrane_grant(void) {
return "Failed to allocate dispatch result";
}
debug("do membrane recv\n");
if (cn_dispatch_invoke(pa, result, pa_membrane_external, CN_MEMBRANE_RECV, NULL) != 0) {
debug("do membrane recv");
if (cn_dispatch_invoke(p, result, membrane_external, CN_MEMBRANE_RECV, NULL) != 0) {
return "Sending on the membrane failed";
}
cptr_t rp_wrapped;
cptr_t wrapped;
res = __cn_dispatch_result_get_cptr_result(result, CN_RP, &rp_wrapped);
res = __cn_dispatch_result_get_cptr_result(result, obj_type, &wrapped);
if (res != NULL) { return res; }
cn_dispatch_result_free(result);
*mem_in = membrane_internal;
*mem_out = membrane_external;
*wrapped_o = wrapped;
return NULL;
}
static char * test_membrane_membrane_grant(void) {
cn_principal_t * pa;
char * res = NULL;
cn_dispatch_result_t * result = NULL;
/* Create the principal */
debug("creating principal");
if (cn_principal_new(&pa) != 0) {
return "Failed to allocate pa";
}
RHOLD_OBJ(pa, dummy_owner);
debug("create test rp");
cptr_t rp;
res = __cn_dispatch_create_single(pa, CN_RP, &rp, NULL);
if (res != NULL) { return res; }
/* Wrap the RP with the membrane */
cptr_t pa_membrane_interal;
cptr_t pa_membrane_external;
cptr_t rp_wrapped;
res = __cn_obj_wrap(pa, rp, CN_RP, &pa_membrane_interal, &pa_membrane_external, &rp_wrapped);
if (res) { return res; }
/* now check all the wrapping invariants. */
struct cnode * cnode;
debug("do checks...\n");
debug("do checks...");
if (cn_principal_get(pa, rp_wrapped, &cnode) != 0) {
return "Failed to get our wrapped rp";
}
......@@ -212,7 +286,7 @@ static char * test_membrane_rp_grant(void) {
/* Create the principal */
debug("creating principal\n");
debug("creating principal");
if (cn_principal_new(&pa) != 0) {
return "Failed to allocate pa";
}
......@@ -223,8 +297,8 @@ static char * test_membrane_rp_grant(void) {
cptr_t pa_membrane_internal;
debug("create membrane internal\n");
res = __cn_dispatch_create_single(pa, CN_MEMBRANE, &pa_membrane_internal);
debug("create membrane internal");
res = __cn_dispatch_create_single(pa, CN_MEMBRANE, &pa_membrane_internal, NULL);
if (res != NULL) { return res; }
/* Create the external membrane from the internal membrane */
......@@ -233,7 +307,7 @@ static char * test_membrane_rp_grant(void) {
return "Failed to allocate dispatch result";
}
debug("create membrane external\n");
debug("create membrane external");
if (cn_dispatch_invoke(pa, result, pa_membrane_internal, CN_MEMBRANE_EXTERNAL, NULL) != 0) {
return "Failed dispatch invoke external on membrane";
}
......@@ -247,9 +321,9 @@ static char * test_membrane_rp_grant(void) {
/* Create a dummy object to send through the membrane */
debug("create test rp\n");
debug("create test rp");
cptr_t rp;
res = __cn_dispatch_create_single(pa, CN_RP, &rp);
res = __cn_dispatch_create_single(pa, CN_RP, &rp, NULL);
if (res != NULL) { return res; }
/* Send the dummy object through the membrane */
......@@ -262,7 +336,7 @@ static char * test_membrane_rp_grant(void) {
return "Failed to allocate dispatch result";
}
debug("do membrane send\n");
debug("do membrane send");
if (cn_dispatch_invoke(pa, result, pa_membrane_internal,
CN_MEMBRANE_SEND, (void *) &membrane_send_args) != 0) {
return "Sending on the membrane failed";
......@@ -279,7 +353,7 @@ static char * test_membrane_rp_grant(void) {
return "Failed to allocate dispatch result";
}
debug("do membrane recv\n");
debug("do membrane recv");
if (cn_dispatch_invoke(pa, result, pa_membrane_external, CN_MEMBRANE_RECV, NULL) != 0) {
return "Sending on the membrane failed";
}
......@@ -293,9 +367,9 @@ static char * test_membrane_rp_grant(void) {
/* Now create another RP and send it through the original RP */
debug("create sender rp\n");
debug("create sender rp");
cptr_t sender_rp;
res = __cn_dispatch_create_single(pa, CN_RP, &sender_rp);
res = __cn_dispatch_create_single(pa, CN_RP, &sender_rp, NULL);
if (res != NULL) { return res; }
/* Send this RP from the unwrapped RP capability */
......@@ -310,7 +384,7 @@ static char * test_membrane_rp_grant(void) {
return "Failed to allocate dispatch result";
}
debug("send sender rp on orig rp\n");
debug("send sender rp on orig rp");
if (cn_dispatch_invoke(pa, result, rp,
CN_RP_SEND, (void *) &rp_send_args) != 0) {
return "Sending on the rp failed";
......@@ -327,14 +401,14 @@ static char * test_membrane_rp_grant(void) {
return "Failed to allocate dispatch result";
}
debug("do rp recv\n");
debug("do rp recv");
if (cn_dispatch_invoke(pa, result, rp_wrapped, CN_RP_RECV, NULL) != 0) {
return "recving on the wrapped rp failed";
}
cptr_t sender_rp_wrapped;
debug("getting rp recv result\n");
debug("getting rp recv result");
res = __cn_dispatch_result_get_cptr_result(result, CN_RP, &sender_rp_wrapped);
if (res != NULL) { return res; }
......@@ -344,7 +418,7 @@ static char * test_membrane_rp_grant(void) {
struct cnode * cnode;
debug("do checks...\n");
debug("do checks...");
if (cn_principal_get(pa, sender_rp_wrapped, &cnode) != 0) {
return "Failed to get our wrapped rp";
......@@ -387,9 +461,107 @@ static char * test_membrane_rp_grant(void) {
return NULL;
}
static char * test_annotated_node_reset(void) {
cn_principal_t *p;
char * res = NULL;
cn_dispatch_result_t * result = NULL;
/* Create the principal */
debug("creating principal");
if (cn_principal_new(&p) != 0) {
return "Failed to allocate p";
}
RHOLD_OBJ(p, dummy_owner);
cn_node_t *node_obj;
if (cn_node_new(&node_obj) != 0) {
return "failed to allocate new node";
}
RHOLD_OBJ(p, node_obj);
debug("inserting node cptr");
cptr_t node_cptr;
if (cn_principal_insert(p, cn_obj_ref(node_obj), NULL, &node_cptr) != 0) {
return "couldn't insert node into principal";
}
debug("grant orig node grant to test principal");
cptr_t orig_node_grant;
cn_grant(node_obj->secret, node_obj->grant, p, NULL, &orig_node_grant);
debug("creating flow to node using its grant");
cn_dispatch_create_flow_args_t flow_args = {
.node_grant = orig_node_grant,
};
cptr_t orig_flow;
res = __cn_dispatch_create_single(p, CN_FLOW, &orig_flow, &flow_args);
if (res) { return res; }
debug("make sure we can deref the new flow");
res = __test_can_deref(p, orig_flow);
if (res) { return res; }
cptr_t wrapped_node;
cptr_t node_wrapping_membrane_in;
cptr_t node_wrapping_membrane_ext;
debug("wrapping the node object");
res = __cn_obj_wrap(p, node_cptr, CN_NODE, &node_wrapping_membrane_in,
&node_wrapping_membrane_ext,
&wrapped_node);
if (res) { return res; }
/* Create a new RP */
debug("create test rp in node c-space");
cptr_t test_cptr;
res = __cn_dispatch_create_single(node_obj->principal, CN_RP, &test_cptr, NULL);
if (res) { return res; }
debug("make sure we can deref the new test-cptr");
res = __test_can_deref(node_obj->principal, test_cptr);
if (res) { return res; }
debug("reset the node");
if (__cn_dispatch_result_new(&result) != 0) {
return "failed to create dispatch result";
}
if (cn_dispatch_invoke(p, result, wrapped_node, CN_NODE_RESET, NULL) != 0) {
return "node reset failed";
}
cptr_t node_grant;
res = __cn_dispatch_result_get_cptr_result(result, CN_NODE_GRANT, &node_grant);
if (res != NULL) { return res; }
cn_dispatch_result_free(result);
debug("check that the node grant is wrapped by the ext membrane");
struct cnode * node_grant_cnode;
res = __test_wrapped_by(p, node_grant, node_wrapping_membrane_ext, &node_grant_cnode);
if (res) { return res; }
cap_cnode_put(node_grant_cnode);
debug("make sure we can't deref the test cptr we put in before");
res = __test_can_not_deref(node_obj->principal, test_cptr);
if (res) { return res; }
debug("make sure we can't deref the original flow we created");
res = __test_can_not_deref(p, orig_flow);
if (res) { return res; }
return NULL;
}
static char * all_tests(void) {
mu_run_test(test_membrane_membrane_grant);
mu_run_test(test_membrane_rp_grant);
mu_run_test(test_annotated_node_reset);
return NULL;
}
......@@ -397,7 +569,7 @@ int main(int argc,char **argv) {
cn_init();
char * result = all_tests();
if (result) {
debug("FAILED: %s\n", result);
debug("FAILED: %s", result);
return 1;
}
return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment