GNUnet  last
testing_api_cmd_finish.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2021 GNUnet e.V.
4 
5  GNUnet is free software: you can redistribute it and/or modify it
6  under the terms of the GNU Affero General Public License as published
7  by the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  GNUnet is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Affero General Public License for more details.
14 
15  You should have received a copy of the GNU Affero General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  SPDX-License-Identifier: AGPL3.0-or-later
19  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "gnunet_testing_ng_lib.h"
28 #include "gnunet_testing_plugin.h"
29 #include "gnunet_testing_barrier.h"
31 
32 
38 {
42  void *cls;
43 
47  const char *async_label;
48 
53 
58 
63 
64 };
65 
66 
73 static void
74 done_finish (void *cls)
75 {
76  struct FinishState *finish_state = cls;
77 
78  GNUNET_SCHEDULER_cancel (finish_state->finish_task);
79  finish_state->finish_task = NULL;
80  GNUNET_TESTING_async_finish (&finish_state->ac);
81 }
82 
83 
90 static void
92 {
93  struct FinishState *finish_state = cls;
94 
95  finish_state->finish_task = NULL;
97  "Timeout waiting for command `%s' to finish\n",
98  finish_state->async_label);
99  GNUNET_TESTING_async_fail (&finish_state->ac);
100 }
101 
102 
108 static void
111 {
112  struct FinishState *finish_state = cls;
113  const struct GNUNET_TESTING_Command *async_cmd;
114  struct GNUNET_TESTING_AsyncContext *aac;
115 
116  async_cmd
118  finish_state->async_label);
119  if (NULL == async_cmd)
120  {
122  "Did not find command `%s'\n",
123  finish_state->async_label);
125  return;
126  }
127  if ( (NULL == (aac = async_cmd->ac)) ||
128  (! async_cmd->asynchronous_finish) )
129  {
131  "Cannot finish `%s': not asynchronous\n",
132  finish_state->async_label);
134  return;
135  }
136  if (GNUNET_NO != aac->finished)
137  {
138  /* Command is already finished, so are we! */
139  GNUNET_TESTING_async_finish (&finish_state->ac);
140  return;
141  }
142  finish_state->finish_task
143  = GNUNET_SCHEDULER_add_delayed (finish_state->timeout,
145  finish_state);
146  aac->cont = &done_finish;
147  aac->cont_cls = finish_state;
148 }
149 
150 
156 static void
157 cleanup_finish (void *cls)
158 {
159  struct FinishState *finish_state = cls;
160 
161  if (NULL != finish_state->finish_task)
162  {
163  GNUNET_SCHEDULER_cancel (finish_state->finish_task);
164  finish_state->finish_task = NULL;
165  }
166  GNUNET_free (finish_state);
167 }
168 
169 
170 const struct GNUNET_TESTING_Command
171 GNUNET_TESTING_cmd_finish (const char *finish_label,
172  const char *cmd_ref,
174 {
175  struct FinishState *finish_state;
176 
177  finish_state = GNUNET_new (struct FinishState);
178  finish_state->async_label = cmd_ref;
179  finish_state->timeout = timeout;
180  return GNUNET_TESTING_command_new (finish_state, finish_label,
181  &run_finish,
183  NULL, &finish_state->ac);
184 }
185 
186 
189 {
190  /* do not permit this function to be used on
191  a finish command! */
192  GNUNET_assert (cmd.run != &run_finish);
193  cmd.asynchronous_finish = true;
194  return cmd;
195 }
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:119
struct GNUNET_TESTING_Interpreter * is
API to manage barriers.
void GNUNET_TESTING_async_finish(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has finished.
void GNUNET_TESTING_async_fail(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has failed.
struct GNUNET_TESTING_Command GNUNET_TESTING_command_new(void *cls, const char *label, GNUNET_TESTING_CommandRunRoutine run, GNUNET_TESTING_CommandCleanupRoutine cleanup, GNUNET_TESTING_CommandGetTraits traits, struct GNUNET_TESTING_AsyncContext *ac)
Create a new command.
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_lookup_command(struct GNUNET_TESTING_Interpreter *is, const char *label)
Lookup command by label.
void GNUNET_TESTING_interpreter_fail(struct GNUNET_TESTING_Interpreter *is)
Current command failed, clean up and fail the test case.
#define GNUNET_log(kind,...)
@ GNUNET_NO
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
@ GNUNET_ERROR_TYPE_ERROR
#define GNUNET_new(type)
Allocate a struct or union of the given type.
#define GNUNET_free(ptr)
Wrapper around free.
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:975
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1272
Struct to use for command-specific context information closure of a command waiting for another comma...
struct GNUNET_TESTING_AsyncContext ac
Function to call when done.
void * cls
Closure for all commands with command-specific context information.
const char * async_label
Label of the asynchronous command the synchronous command of this closure waits for.
struct GNUNET_TIME_Relative timeout
How long to wait until finish fails hard?
struct GNUNET_SCHEDULER_Task * finish_task
Task for running the finish method of the asynchronous task the command is waiting for.
Entry in list of pending tasks.
Definition: scheduler.c:136
State each asynchronous command must have in its closure.
GNUNET_SCHEDULER_TaskCallback cont
Function to call when done.
void * cont_cls
Closure for cont.
enum GNUNET_GenericReturnValue finished
Indication if the command finished (GNUNET_OK).
A command to be run by the interpreter.
struct GNUNET_TESTING_AsyncContext * ac
Pointer to the asynchronous context in the command's closure.
bool asynchronous_finish
If "true", the interpreter should not immediately call finish, even if finish is non-NULL.
Global state of the interpreter, used by a command to access information about other commands.
Time for relative time used by GNUnet, in microseconds.
static void timeout_finish(void *cls)
Function triggered if the command we are waiting for did not complete on time.
static void cleanup_finish(void *cls)
Cleanup state of a finish command.
const struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_finish(const char *finish_label, const char *cmd_ref, struct GNUNET_TIME_Relative timeout)
Create (synchronous) command that waits for another command to finish.
struct GNUNET_TESTING_Command GNUNET_TESTING_cmd_make_unblocking(struct GNUNET_TESTING_Command cmd)
Turn asynchronous command into non-blocking command by setting asynchronous_finish to true.
static void run_finish(void *cls, struct GNUNET_TESTING_Interpreter *is)
Run method of the command created by the interpreter to wait for another command to finish.
static void done_finish(void *cls)
Function called when the command we are waiting on is finished.