first batch of license fixes (boring)
[oweals/gnunet.git] / src / testbed-logger / test_testbed_logger_api.c
1 /*
2       This file is part of GNUnet
3       Copyright (C) 2008--2013 GNUnet e.V.
4
5       GNUnet is free software: you can redistribute it and/or modify it
6       under the terms of the GNU 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 /**
16  * @file testbed-logger/test_testbed_logger_api.c
17  * @brief testcases for the testbed logger api
18  * @author Sree Harsha Totakura
19  */
20 #include "platform.h"
21 #include "gnunet_util_lib.h"
22 #include "gnunet_testing_lib.h"
23 #include "gnunet_testbed_logger_service.h"
24
25 /**
26  * Generic logging shortcut
27  */
28 #define LOG(kind,...)                           \
29   GNUNET_log (kind, __VA_ARGS__)
30
31 /**
32  * Relative time seconds shorthand
33  */
34 #define TIME_REL_SECS(sec) \
35   GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
36
37 /**
38  * Opaque handle for the logging service
39  */
40 static struct GNUNET_TESTBED_LOGGER_Handle *h;
41
42 static struct GNUNET_TESTING_Peer *peer;
43
44 static char *search_dir;
45
46 /**
47  * Abort task identifier
48  */
49 static struct GNUNET_SCHEDULER_Task *abort_task;
50 static struct GNUNET_SCHEDULER_Task *write_task;
51
52 static int result;
53
54 #define CANCEL_TASK(task) do {                  \
55     if (NULL != task) \
56     {                                           \
57       GNUNET_SCHEDULER_cancel (task);     \
58       task = NULL;    \
59     }                                           \
60   } while (0)
61
62 /**
63  * shortcut to exit during failure
64  */
65 #define FAIL_TEST(cond, ret) do {                               \
66     if (!(cond)) {                                              \
67       GNUNET_break(0);                                          \
68       CANCEL_TASK (abort_task);                                 \
69       abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL);  \
70       ret;                                                      \
71     }                                                           \
72   } while (0)
73
74
75 /**
76  * Shutdown nicely
77  *
78  * @param cls NULL
79  * @param tc the task context
80  */
81 static void
82 shutdown_now ()
83 {
84   CANCEL_TASK (abort_task);
85   CANCEL_TASK (write_task);
86   GNUNET_free_non_null (search_dir);
87   if (NULL != h)
88     GNUNET_TESTBED_LOGGER_disconnect (h);
89   GNUNET_SCHEDULER_shutdown ();
90 }
91
92
93 static void
94 do_abort (void *cls)
95 {
96   LOG (GNUNET_ERROR_TYPE_WARNING,
97        "Aborting\n");
98   abort_task = NULL;
99   shutdown_now ();
100 }
101
102
103 #define BSIZE 1024
104
105
106 /**
107  * Function called to iterate over a directory.
108  *
109  * @param cls closure
110  * @param filename complete filename (absolute path)
111  * @return #GNUNET_OK to continue to iterate,
112  *  #GNUNET_NO to stop iteration with no error,
113  *  #GNUNET_SYSERR to abort iteration with error!
114  */
115 static int
116 iterator_cb (void *cls,
117              const char *filename)
118 {
119   const char *fn;
120   size_t len;
121   uint64_t fs;
122
123   LOG (GNUNET_ERROR_TYPE_DEBUG,
124        "Iterator sees file %s\n",
125        filename);
126   len = strlen (filename);
127   fn = filename + len;
128   if (0 != strcasecmp (".dat", fn - 4))
129     return GNUNET_OK;
130   if (GNUNET_OK !=
131       GNUNET_DISK_file_size (filename,
132                              &fs,
133                              GNUNET_NO,
134                              GNUNET_YES))
135   {
136     LOG (GNUNET_ERROR_TYPE_DEBUG,
137          "Failed to obtain file size for file %s\n",
138          filename);
139     return GNUNET_SYSERR;
140   }
141   if ((BSIZE * 2) != fs)
142   {
143     LOG (GNUNET_ERROR_TYPE_DEBUG,
144          "Unexpected file size for file %s\n",
145          filename);
146     /* The file size should be equal to what we
147        have written */
148     return GNUNET_SYSERR;
149   }
150   result = GNUNET_OK;
151   return GNUNET_OK;
152 }
153
154
155 /**
156  * Functions of this type are called to notify a successful
157  * transmission of the message to the logger service
158  *
159  * @param cls the closure given to GNUNET_TESTBED_LOGGER_send()
160  * @param size the amount of data sent
161  */
162 static void
163 flush_comp (void *cls,
164             size_t size)
165 {
166   LOG (GNUNET_ERROR_TYPE_DEBUG,
167        "Flush running\n");
168   FAIL_TEST (&write_task == cls,
169              return);
170   FAIL_TEST ((BSIZE * 2) == size,
171              return);
172   FAIL_TEST (GNUNET_OK ==
173              GNUNET_TESTING_peer_stop (peer),
174              return);
175   LOG (GNUNET_ERROR_TYPE_DEBUG,
176        "Peer stopped, scanning %s\n",
177        search_dir);
178   FAIL_TEST (GNUNET_SYSERR !=
179              GNUNET_DISK_directory_scan (search_dir,
180                                          &iterator_cb,
181                                          NULL),
182              return);
183   shutdown_now ();
184 }
185
186
187 static void
188 do_write (void *cls)
189 {
190   static int i;
191   char buf[BSIZE];
192
193   write_task = NULL;
194   LOG (GNUNET_ERROR_TYPE_DEBUG,
195        "Write task running\n");
196   if (0 == i)
197     write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1),
198                                                &do_write,
199                                                NULL);
200   (void) memset (buf, i, BSIZE);
201   GNUNET_TESTBED_LOGGER_write (h,
202                                buf,
203                                BSIZE);
204   if (0 == i++)
205     return;
206   GNUNET_TESTBED_LOGGER_flush (h,
207                                &flush_comp,
208                                &write_task);
209 }
210
211
212 /**
213  * Signature of the 'main' function for a (single-peer) testcase that
214  * is run using #GNUNET_TESTING_peer_run().
215  *
216  * @param cls closure
217  * @param cfg configuration of the peer that was started
218  * @param peer identity of the peer that was created
219  */
220 static void
221 test_main (void *cls,
222            const struct GNUNET_CONFIGURATION_Handle *cfg,
223            struct GNUNET_TESTING_Peer *p)
224 {
225   LOG (GNUNET_ERROR_TYPE_DEBUG,
226        "Connecting to logger\n");
227   FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)),
228              return);
229   FAIL_TEST (GNUNET_OK ==
230              GNUNET_CONFIGURATION_get_value_filename (cfg,
231                                                       "testbed-logger",
232                                                       "dir",
233                                                       &search_dir),
234              return);
235   peer = p;
236   write_task = GNUNET_SCHEDULER_add_now (&do_write,
237                                          NULL);
238   abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10),
239                                              &do_abort,
240                                              NULL);
241 }
242
243
244 /**
245  * Main function
246  */
247 int
248 main (int argc, char **argv)
249 {
250   int ret;
251
252   result = GNUNET_SYSERR;
253   GNUNET_log_setup ("test-testbed-logger-api",
254                     "WARNING",
255                     NULL);
256   GNUNET_break (GNUNET_OK ==
257                 GNUNET_DISK_directory_remove ("/tmp/test-testbed"));
258   ret = GNUNET_TESTING_service_run ("test-testbed-logger",
259                                     "testbed-logger",
260                                     "test_testbed_logger_api.conf",
261                                     &test_main,
262                                     NULL);
263   GNUNET_break (GNUNET_OK ==
264                 GNUNET_DISK_directory_remove ("/tmp/test-testbed"));
265   if (0 != ret)
266     return 1;
267   if (GNUNET_OK != result)
268     return 2;
269   return 0;
270 }