GNUnet  0.11.x
Data Structures | Macros | Functions
testing_api_cmd_netjail_start_testsystem.c File Reference
#include "platform.h"
#include "gnunet_testing_ng_lib.h"
#include "testing_cmds.h"
Include dependency graph for testing_api_cmd_netjail_start_testsystem.c:

Go to the source code of this file.

Data Structures

struct  HelperMessage
 Struct to store messages send/received by the helper into a DLL. More...
 
struct  NetJailState
 Struct to hold information for callbacks. More...
 
struct  TestingSystemCount
 Struct containing the number of the test environment and the NetJailState which will be handed to callbacks specific to a test environment. More...
 

Macros

#define NETJAIL_EXEC_SCRIPT   "./../testing/netjail_exec.sh"
 

Functions

static void netjail_exec_cleanup (void *cls, const struct GNUNET_TESTING_Command *cmd)
 Code to clean up resource this cmd used. More...
 
static int netjail_exec_traits (void *cls, const void **ret, const char *trait, unsigned int index)
 This function prepares an array with traits. More...
 
int GNUNET_TESTING_get_trait_helper_handles (const struct GNUNET_TESTING_Command *cmd, struct GNUNET_HELPER_Handle ***helper)
 Offer handles to testing cmd helper from trait. More...
 
static void clear_msg (void *cls, int result)
 Continuation function from GNUNET_HELPER_send() More...
 
static int helper_mst (void *cls, const struct GNUNET_MessageHeader *message)
 Functions with this signature are called whenever a complete message is received by the tokenizer. More...
 
static void exp_cb (void *cls)
 Callback called if there was an exception during execution of the helper. More...
 
static struct GNUNET_CMDS_HelperInitcreate_helper_init_msg_ (char *m_char, char *n_char, const char *plugin_name)
 Function to initialize a init message for the helper. More...
 
static void start_helper (struct NetJailState *ns, struct GNUNET_CONFIGURATION_Handle *config, char *m_char, char *n_char)
 Function which start a single helper process. More...
 
static void netjail_exec_run (void *cls, const struct GNUNET_TESTING_Command *cmd, struct GNUNET_TESTING_Interpreter *is)
 This function starts a helper process for each node. More...
 
static int netjail_start_finish (void *cls, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
 This function checks on three different information. More...
 
struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_netjail_start_testing_system (const char *label, char *local_m, char *global_n, char *plugin_name, unsigned int *rv)
 Create command. More...
 

Macro Definition Documentation

◆ NETJAIL_EXEC_SCRIPT

#define NETJAIL_EXEC_SCRIPT   "./../testing/netjail_exec.sh"

Definition at line 30 of file testing_api_cmd_netjail_start_testsystem.c.

Function Documentation

◆ netjail_exec_cleanup()

static void netjail_exec_cleanup ( void *  cls,
const struct GNUNET_TESTING_Command cmd 
)
static

Code to clean up resource this cmd used.

Parameters
clsclosure
cmdcurrent CMD being cleaned up.

Definition at line 200 of file testing_api_cmd_netjail_start_testsystem.c.

202 {
203  struct NetJailState *ns = cls;
204  struct HelperMessage *message_pos;
205  struct TestingSystemCount *tbc_pos;
206 
207  while (NULL != (message_pos = ns->hp_messages_head))
208  {
209  GNUNET_CONTAINER_DLL_remove (ns->hp_messages_head,
210  ns->hp_messages_tail,
211  message_pos);
212  GNUNET_free (message_pos);
213  }
214  while (NULL != (tbc_pos = ns->tbcs_head))
215  {
216  GNUNET_CONTAINER_DLL_remove (ns->tbcs_head,
217  ns->tbcs_tail,
218  tbc_pos);
219  GNUNET_free (tbc_pos);
220  }
221  GNUNET_free (ns);
222 }
static struct GNUNET_NAMESTORE_Handle * ns
Handle to the namestore.
Definition: gnunet-abd.c:41
#define GNUNET_CONTAINER_DLL_remove(head, tail, element)
Remove an element from a DLL.
#define GNUNET_free(ptr)
Wrapper around free.
Struct to store messages send/received by the helper into a DLL.
Struct to hold information for callbacks.
Struct containing the number of the test environment and the NetJailState which will be handed to cal...

References GNUNET_CONTAINER_DLL_remove, GNUNET_free, and ns.

◆ netjail_exec_traits()

static int netjail_exec_traits ( void *  cls,
const void **  ret,
const char *  trait,
unsigned int  index 
)
static

This function prepares an array with traits.

Definition at line 230 of file testing_api_cmd_netjail_start_testsystem.c.

234 {
235  struct NetJailState *ns = cls;
236  struct GNUNET_HELPER_Handle **helper = ns->helper;
237  struct HelperMessage *hp_messages_head = ns->hp_messages_head;
238 
239 
240  struct GNUNET_TESTING_Trait traits[] = {
241  {
242  .index = 0,
243  .trait_name = "helper_handles",
244  .ptr = (const void *) helper,
245  },
246  {
247  .index = 1,
248  .trait_name = "hp_msgs_head",
249  .ptr = (const void *) hp_messages_head,
250  },
252  };
253 
254  return GNUNET_TESTING_get_trait (traits,
255  ret,
256  trait,
257  index);
258 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
struct GNUNET_TESTING_Trait GNUNET_TESTING_trait_end(void)
"end" trait.
int GNUNET_TESTING_get_trait(const struct GNUNET_TESTING_Trait *traits, const void **ret, const char *trait, unsigned int index)
Extract a trait.
The handle to a helper process.
Definition: helper.c:79
unsigned int index
Index number associated with the trait.

References GNUNET_TESTING_get_trait(), GNUNET_TESTING_trait_end(), GNUNET_TESTING_Trait::index, ns, and ret.

Here is the call graph for this function:

◆ GNUNET_TESTING_get_trait_helper_handles()

int GNUNET_TESTING_get_trait_helper_handles ( const struct GNUNET_TESTING_Command cmd,
struct GNUNET_HELPER_Handle ***  helper 
)

Offer handles to testing cmd helper from trait.

Parameters
cmdcommand to extract the message from.
ptpointer to message.
Returns
GNUNET_OK on success.

Definition at line 269 of file testing_api_cmd_netjail_start_testsystem.c.

272 {
273  return cmd->traits (cmd->cls,
274  (const void **) helper,
275  "helper_handles",
276  (unsigned int) 0);
277 }
int(* traits)(void *cls, const void **ret, const char *trait, unsigned int index)
Extract information from a command that is useful for other commands.
void * cls
Closure for all commands with command-specific context information.

References GNUNET_TESTING_Command::cls, and GNUNET_TESTING_Command::traits.

Referenced by stop_testing_system_run().

Here is the caller graph for this function:

◆ clear_msg()

static void clear_msg ( void *  cls,
int  result 
)
static

Continuation function from GNUNET_HELPER_send()

Parameters
clsclosure
resultGNUNET_OK on success, GNUNET_NO if helper process died GNUNET_SYSERR during GNUNET_HELPER_stop

Definition at line 289 of file testing_api_cmd_netjail_start_testsystem.c.

290 {
291  struct TestingSystemCount *tbc = cls;
292  struct NetJailState *ns = tbc->ns;
293 
294  GNUNET_assert (NULL != ns->shandle[tbc->count - 1]);
295  ns->shandle[tbc->count - 1] = NULL;
296  GNUNET_free (ns->msg[tbc->count - 1]);
297  ns->msg[tbc->count - 1] = NULL;
298 }
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
unsigned int count
The number of the test environment.
struct NetJailState * ns
Struct to store information handed over to callbacks.

References TestingSystemCount::count, GNUNET_assert, GNUNET_free, ns, and TestingSystemCount::ns.

Referenced by netjail_start_finish(), and start_helper().

Here is the caller graph for this function:

◆ helper_mst()

static int helper_mst ( void *  cls,
const struct GNUNET_MessageHeader message 
)
static

Functions with this signature are called whenever a complete message is received by the tokenizer.

Do not call GNUNET_SERVER_mst_destroy in callback

Parameters
clsclosure
clientidentification of the client
messagethe actual message
Returns
GNUNET_OK on success, GNUNET_SYSERR to stop further processing

Definition at line 314 of file testing_api_cmd_netjail_start_testsystem.c.

315 {
316  struct TestingSystemCount *tbc = cls;
317  struct NetJailState *ns = tbc->ns;
318  struct HelperMessage *hp_msg;
319 
320  if (GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY == ntohs (message->type))
321  {
322  ns->number_of_testsystems_started++;
323  }
325  message->type))
326  {
327  ns->number_of_peers_started++;
328  }
330  message->type))
331  {
332  ns->number_of_local_test_finished++;
333  }
334  else
335  {
336  hp_msg = GNUNET_new (struct HelperMessage);
337  hp_msg->bytes_msg = message->size;
338  memcpy (&hp_msg[1], message, message->size);
339  GNUNET_CONTAINER_DLL_insert (ns->hp_messages_head, ns->hp_messages_tail,
340  hp_msg);
341  }
342 
343  return GNUNET_OK;
344 }
@ GNUNET_OK
Definition: gnunet_common.h:95
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED
#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED
#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY
The reply message from gnunet-cmds-helper.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
uint16_t bytes_msg
Size of the original message.

References HelperMessage::bytes_msg, GNUNET_CONTAINER_DLL_insert, GNUNET_MESSAGE_TYPE_CMDS_HELPER_LOCAL_FINISHED, GNUNET_MESSAGE_TYPE_CMDS_HELPER_PEER_STARTED, GNUNET_MESSAGE_TYPE_CMDS_HELPER_REPLY, GNUNET_new, GNUNET_OK, ns, TestingSystemCount::ns, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by start_helper().

Here is the caller graph for this function:

◆ exp_cb()

static void exp_cb ( void *  cls)
static

Callback called if there was an exception during execution of the helper.

Definition at line 352 of file testing_api_cmd_netjail_start_testsystem.c.

353 {
354  struct NetJailState *ns = cls;
355  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Called exp_cb.\n");
356  *ns->rv = 1;
357 }
#define GNUNET_log(kind,...)
@ GNUNET_ERROR_TYPE_DEBUG

References GNUNET_ERROR_TYPE_DEBUG, GNUNET_log, and ns.

Referenced by GNUNET_HELPER_start(), and start_helper().

Here is the caller graph for this function:

◆ create_helper_init_msg_()

static struct GNUNET_CMDS_HelperInit* create_helper_init_msg_ ( char *  m_char,
char *  n_char,
const char *  plugin_name 
)
static

Function to initialize a init message for the helper.

Parameters
m_charThe actual node in a namespace. //TODO Change this to unsigned int
n_charThe actual namespace. //TODO Change this to unsigned int
plugin_nameName of the test case plugin the helper will load.

Definition at line 369 of file testing_api_cmd_netjail_start_testsystem.c.

372 {
373  struct GNUNET_CMDS_HelperInit *msg;
374  uint16_t plugin_name_len;
375  uint16_t msg_size;
376 
377  GNUNET_assert (NULL != plugin_name);
378  plugin_name_len = strlen (plugin_name);
379  msg_size = sizeof(struct GNUNET_CMDS_HelperInit) + plugin_name_len;
380  msg = GNUNET_malloc (msg_size);
381  msg->header.size = htons (msg_size);
383  msg->plugin_name_size = htons (plugin_name_len);
384  GNUNET_memcpy ((char *) &msg[1],
385  plugin_name,
386  plugin_name_len);
387  return msg;
388 }
struct GNUNET_MessageHeader * msg
Definition: 005.c:2
static char * plugin_name
Name of our plugin.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_malloc(size)
Wrapper around malloc.
#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT
The initialization message towards gnunet-cmds-helper.
Initialization message for gnunet-cmds-testbed to start cmd binary.
Definition: testing_cmds.h:38

References GNUNET_assert, GNUNET_malloc, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_CMDS_HELPER_INIT, msg, plugin_name, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Referenced by start_helper().

Here is the caller graph for this function:

◆ start_helper()

static void start_helper ( struct NetJailState ns,
struct GNUNET_CONFIGURATION_Handle config,
char *  m_char,
char *  n_char 
)
static

Function which start a single helper process.

Definition at line 396 of file testing_api_cmd_netjail_start_testsystem.c.

400 {
401  struct GNUNET_HELPER_Handle *helper;
402  struct GNUNET_CMDS_HelperInit *msg;
403  struct TestingSystemCount *tbc;
404  char *const script_argv[] = {NETJAIL_EXEC_SCRIPT,
405  m_char,
406  n_char,
409  ns->global_n,
410  ns->local_m,
411  NULL};
412  unsigned int m = atoi (m_char);
413  unsigned int n = atoi (n_char);
414  unsigned int helper_check = GNUNET_OS_check_helper_binary (
416  GNUNET_YES,
417  NULL);
418 
419  tbc = GNUNET_new (struct TestingSystemCount);
420  tbc->ns = ns;
421  tbc->count = (n - 1) * atoi (ns->local_m) + m;
422 
423  GNUNET_CONTAINER_DLL_insert (ns->tbcs_head, ns->tbcs_tail,
424  tbc);
425 
426 
427  if (GNUNET_NO == helper_check)
428  {
430  "No SUID for %s!\n",
432  *ns->rv = 1;
433  }
434  else if (GNUNET_NO == helper_check)
435  {
437  "%s not found!\n",
439  *ns->rv = 1;
440  }
441 
442  GNUNET_array_append (ns->helper, ns->n_helper, GNUNET_HELPER_start (
443  GNUNET_YES,
445  script_argv,
446  &helper_mst,
447  &exp_cb,
448  tbc));
449 
450  helper = ns->helper[tbc->count - 1];
451 
452  msg = create_helper_init_msg_ (m_char,
453  n_char,
454  ns->plugin_name);
455  GNUNET_array_append (ns->msg, ns->n_msg, &msg->header);
456 
457  GNUNET_array_append (ns->shandle, ns->n_shandle, GNUNET_HELPER_send (
458  helper,
459  &msg->header,
460  GNUNET_NO,
461  &clear_msg,
462  tbc));
463 
464  if (NULL == ns->shandle[tbc->count - 1])
465  {
467  "Send handle is NULL!\n");
468  GNUNET_free (msg);
469  *ns->rv = 1;
470  }
471 }
static struct GNUNET_ARM_MonitorHandle * m
Monitor connection with ARM.
Definition: gnunet-arm.c:104
@ GNUNET_YES
Definition: gnunet_common.h:97
@ GNUNET_NO
Definition: gnunet_common.h:94
struct GNUNET_HELPER_SendHandle * GNUNET_HELPER_send(struct GNUNET_HELPER_Handle *h, const struct GNUNET_MessageHeader *msg, int can_drop, GNUNET_HELPER_Continuation cont, void *cont_cls)
Send an message to the helper.
Definition: helper.c:657
struct GNUNET_HELPER_Handle * GNUNET_HELPER_start(int with_control_pipe, const char *binary_name, char *const binary_argv[], GNUNET_MessageTokenizerCallback cb, GNUNET_HELPER_ExceptionCallback exp_cb, void *cb_cls)
Starts a helper and begins reading from it.
Definition: helper.c:491
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_array_append(arr, len, element)
Append an element to an array (growing the array by one).
char * GNUNET_OS_get_libexec_binary_path(const char *progname)
Given the name of a gnunet-helper, gnunet-service or gnunet-daemon binary, try to prefix it with the ...
int GNUNET_OS_check_helper_binary(const char *binary, int check_suid, const char *params)
Check whether an executable exists and possibly if the suid bit is set on the file.
static void exp_cb(void *cls)
Callback called if there was an exception during execution of the helper.
static void clear_msg(void *cls, int result)
Continuation function from GNUNET_HELPER_send()
static struct GNUNET_CMDS_HelperInit * create_helper_init_msg_(char *m_char, char *n_char, const char *plugin_name)
Function to initialize a init message for the helper.
static int helper_mst(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer.
#define HELPER_CMDS_BINARY
Definition: testing_cmds.h:30

References clear_msg(), TestingSystemCount::count, create_helper_init_msg_(), exp_cb(), GNUNET_array_append, GNUNET_CONTAINER_DLL_insert, GNUNET_ERROR_TYPE_ERROR, GNUNET_free, GNUNET_HELPER_send(), GNUNET_HELPER_start(), GNUNET_log, GNUNET_new, GNUNET_NO, GNUNET_OS_check_helper_binary(), GNUNET_OS_get_libexec_binary_path(), GNUNET_YES, HELPER_CMDS_BINARY, helper_mst(), m, msg, NETJAIL_EXEC_SCRIPT, ns, and TestingSystemCount::ns.

Referenced by netjail_exec_run().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ netjail_exec_run()

static void netjail_exec_run ( void *  cls,
const struct GNUNET_TESTING_Command cmd,
struct GNUNET_TESTING_Interpreter is 
)
static

This function starts a helper process for each node.

Parameters
clsclosure.
cmdCMD being run.
isinterpreter state.

Definition at line 482 of file testing_api_cmd_netjail_start_testsystem.c.

485 {
486  char str_m[12];
487  char str_n[12];
488  struct NetJailState *ns = cls;
491 
492  for (int i = 1; i <= atoi (ns->global_n); i++)
493  {
494  for (int j = 1; j <= atoi (ns->local_m); j++)
495  {
496  sprintf (str_n, "%d", i);
497  sprintf (str_m, "%d", j);
499  str_m,
500  str_n);
501  }
502  }
503 }
static const struct GNUNET_CONFIGURATION_Handle * config
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
static void start_helper(struct NetJailState *ns, struct GNUNET_CONFIGURATION_Handle *config, char *m_char, char *n_char)
Function which start a single helper process.

References config, GNUNET_CONFIGURATION_create(), ns, and start_helper().

Here is the call graph for this function:

◆ netjail_start_finish()

static int netjail_start_finish ( void *  cls,
GNUNET_SCHEDULER_TaskCallback  cont,
void *  cont_cls 
)
static

This function checks on three different information.

  1. Did all helpers start. This is only logged.
  2. Did all peer start. In this case a GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED is send to all peers.
  3. Did all peers finished the test case. In this case interpreter_next will be called.

Definition at line 516 of file testing_api_cmd_netjail_start_testsystem.c.

519 {
520  unsigned int ret = GNUNET_NO;
521  struct NetJailState *ns = cls;
522  unsigned int total_number = atoi (ns->local_m) * atoi (ns->global_n);
523  struct GNUNET_CMDS_ALL_PEERS_STARTED *reply;
524  size_t msg_length;
525  struct GNUNET_HELPER_Handle *helper;
526  struct TestingSystemCount *tbc;
527 
528  if (ns->number_of_local_test_finished == total_number)
529  {
530  ret = GNUNET_YES;
531  cont (cont_cls);
532  }
533 
534  if (ns->number_of_testsystems_started == total_number)
535  {
536  ns->number_of_testsystems_started = 0;
537  }
538 
539  if (ns->number_of_peers_started == total_number)
540  {
541  for (int i = 1; i <= atoi (ns->global_n); i++)
542  {
543  for (int j = 1; j <= atoi (ns->local_m); j++)
544  {
545  tbc = GNUNET_new (struct TestingSystemCount);
546  tbc->ns = ns;
547  // TODO This needs to be more generic. As we send more messages back and forth, we can not grow the arrays again and again, because this is to error prone.
548  tbc->count = (i - 1) * atoi (ns->local_m) + j + total_number;
549 
550  helper = ns->helper[tbc->count - 1 - total_number];
551  msg_length = sizeof(struct GNUNET_CMDS_ALL_PEERS_STARTED);
552  reply = GNUNET_new (struct GNUNET_CMDS_ALL_PEERS_STARTED);
553  reply->header.type = htons (
555  reply->header.size = htons ((uint16_t) msg_length);
556 
557  GNUNET_array_append (ns->msg, ns->n_msg, &reply->header);
558 
560  helper,
561  &reply->header,
562  GNUNET_NO,
563  &clear_msg,
564  tbc);
565 
566  GNUNET_array_append (ns->shandle, ns->n_shandle, sh);
567  }
568  }
569  ns->number_of_peers_started = 0;
570  }
571  return ret;
572 }
static struct SolverHandle * sh
#define GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED
struct GNUNET_MessageHeader header
Type is GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED.
Definition: testing_cmds.h:77
Entry in the queue of messages we need to transmit to the helper.
Definition: helper.c:37

References clear_msg(), TestingSystemCount::count, GNUNET_array_append, GNUNET_HELPER_send(), GNUNET_MESSAGE_TYPE_CMDS_HELPER_ALL_PEERS_STARTED, GNUNET_new, GNUNET_NO, GNUNET_YES, GNUNET_CMDS_ALL_PEERS_STARTED::header, ns, TestingSystemCount::ns, ret, sh, GNUNET_MessageHeader::size, and GNUNET_MessageHeader::type.

Here is the call graph for this function:

◆ GNUNET_TESTING_cmd_netjail_start_testing_system()

struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_netjail_start_testing_system ( const char *  label,
char *  local_m,
char *  global_n,
char *  plugin_name,
unsigned int *  rv 
)

Create command.

Parameters
labelName for the command.
local_mNumber of nodes in a network namespace. //TODO make this a unsigned int
global_nNumber of network namespaces. //TODO make this a unsigned int
plugin_nameName of the test case plugin the helper will load.
rvPointer to the return value of the test.
Returns
command.

Definition at line 516 of file testing_api_cmd_netjail_start_testsystem.c.

591 {
592  struct NetJailState *ns;
593 
594  ns = GNUNET_new (struct NetJailState);
595  ns->local_m = local_m;
596  ns->global_n = global_n;
597  ns->plugin_name = plugin_name;
598  ns->rv = rv;
599 
600  struct GNUNET_TESTING_Command cmd = {
601  .cls = ns,
602  .label = label,
603  .run = &netjail_exec_run,
604  .finish = &netjail_start_finish,
605  .cleanup = &netjail_exec_cleanup,
606  .traits = &netjail_exec_traits
607  };
608 
609  return cmd;
610 }
A command to be run by the interpreter.
const char * label
Label for the command.
char * local_m
Number of nodes in a network namespace.
unsigned int * rv
Pointer to the return value of the test.
char * global_n
Number of network namespaces.
static int netjail_exec_traits(void *cls, const void **ret, const char *trait, unsigned int index)
This function prepares an array with traits.
static int netjail_start_finish(void *cls, GNUNET_SCHEDULER_TaskCallback cont, void *cont_cls)
This function checks on three different information.
static void netjail_exec_run(void *cls, const struct GNUNET_TESTING_Command *cmd, struct GNUNET_TESTING_Interpreter *is)
This function starts a helper process for each node.
static void netjail_exec_cleanup(void *cls, const struct GNUNET_TESTING_Command *cmd)
Code to clean up resource this cmd used.