GNUnet 0.22.2
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_lib.h"
28
29
35{
39 void *cls;
40
45 const char *async_label;
46
51
56
62
67
72
73};
74
75
82static void
83done_finish (void *cls)
84{
85 struct FinishState *finish_state = cls;
86
88 finish_state->finish_task = NULL;
89 if (NULL != finish_state->old_notify)
90 {
91 finish_state->old_notify (finish_state->old_notify_cls);
92 finish_state->old_notify = NULL;
93 }
94 GNUNET_TESTING_async_finish (&finish_state->ac);
95}
96
97
104static void
106{
107 struct FinishState *finish_state = cls;
108
109 finish_state->finish_task = NULL;
111 "Timeout waiting for command `%s' to finish\n",
112 finish_state->async_label);
113 GNUNET_TESTING_async_fail (&finish_state->ac);
114}
115
116
122static void
124 void *cls,
126{
127 struct FinishState *finish_state = cls;
128 const struct GNUNET_TESTING_Command *async_cmd;
129 struct GNUNET_TESTING_AsyncContext *aac;
130
131 async_cmd
133 finish_state->async_label);
134 if (NULL == async_cmd)
135 {
137 "Did not find command `%s'\n",
138 finish_state->async_label);
140 }
141 if ( (NULL == (aac = async_cmd->ac)) ||
142 (! async_cmd->asynchronous_finish) )
143 {
145 "Cannot finish `%s': not asynchronous\n",
146 finish_state->async_label);
148 }
149 if (aac->finished)
150 {
151 /* Command is already finished, so are we! */
152 GNUNET_TESTING_async_finish (&finish_state->ac);
153 return;
154 }
155 /* add timeout */
156 finish_state->finish_task
157 = GNUNET_SCHEDULER_add_delayed (finish_state->timeout,
159 finish_state);
160 /* back up old notification that we will override */
161 finish_state->old_notify = aac->notify_finished;
162 finish_state->old_notify_cls = aac->notify_finished_cls;
164 aac->notify_finished_cls = finish_state;
165}
166
167
173static void
174cleanup_finish (void *cls)
175{
176 struct FinishState *finish_state = cls;
177
178 if (NULL != finish_state->finish_task)
179 {
180 GNUNET_SCHEDULER_cancel (finish_state->finish_task);
181 finish_state->finish_task = NULL;
182 }
183 GNUNET_free (finish_state);
184}
185
186
187const struct GNUNET_TESTING_Command
189 const char *finish_label,
190 const char *cmd_ref,
192{
193 struct FinishState *finish_state;
194
195 finish_state = GNUNET_new (struct FinishState);
196 finish_state->async_label = cmd_ref;
197 finish_state->timeout = timeout;
199 finish_state,
200 finish_label,
201 &run_finish,
203 NULL,
204 &finish_state->ac);
205}
206
207
210 struct GNUNET_TESTING_Command cmd)
211{
212 /* do not permit this function to be used on
213 a finish command! */
214 GNUNET_assert (cmd.run != &run_finish);
215 cmd.asynchronous_finish = true;
216 return cmd;
217}
static struct GNUNET_TIME_Relative timeout
User defined timestamp for completing operations.
Definition: gnunet-arm.c:118
static struct GNUNET_TESTING_Interpreter * is
struct GNUNET_TESTING_Command GNUNET_TESTING_command_new_ac(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 that may be asynchronous.
void GNUNET_TESTING_async_finish(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has finished.
#define GNUNET_TESTING_FAIL(is)
Print failing line number and trigger shutdown.
void GNUNET_TESTING_async_fail(struct GNUNET_TESTING_AsyncContext *ac)
The asynchronous command of ac has failed.
const struct GNUNET_TESTING_Command * GNUNET_TESTING_interpreter_lookup_command(struct GNUNET_TESTING_Interpreter *is, const char *label)
Lookup command by label.
#define GNUNET_log(kind,...)
#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:980
void(* GNUNET_SCHEDULER_TaskCallback)(void *cls)
Signature of the main function of a task.
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:1277
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.
GNUNET_SCHEDULER_TaskCallback old_notify
Function to call when async operation is done.
void * old_notify_cls
Closure for notify_finished.
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 notify_finished
Function to call when async operation is done.
enum GNUNET_GenericReturnValue finished
Indication if the command finished (GNUNET_OK).
void * notify_finished_cls
Closure for notify_finished.
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 run the next command, even if this command did not ...
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.