2002-05-08 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / tests / t-data.c
1 /* t-data - Regression tests for the GpgmeData abstraction.
2  *      Copyright (C) 2001 g10 Code GmbH
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GPGME is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <stddef.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include <gpgme.h>
28
29 #define fail_if_err(a) do { if(a) {                                       \
30                                fprintf (stderr, "%s:%d: (%i) GpgmeError " \
31                                 "%s\n", __FILE__, __LINE__, round,        \
32                                 gpgme_strerror(a));                       \
33                                 exit (1); }                               \
34                              } while(0)
35
36 static char *
37 make_filename (const char *fname)
38 {
39   const char *srcdir = getenv ("srcdir");
40   char *buf;
41
42   if (!srcdir)
43     srcdir = ".";
44   buf = malloc (strlen(srcdir) + strlen(fname) + 2 );
45   if (!buf)
46     {
47       fprintf (stderr, "%s:%d: could not allocate string: %s\n",
48                __FILE__, __LINE__, strerror (errno));
49       exit (1);
50     }
51   strcpy (buf, srcdir);
52   strcat (buf, "/");
53   strcat (buf, fname);
54   return buf;
55 }
56
57 typedef enum
58   {
59     TEST_INITIALIZER,
60     TEST_INVALID_ARGUMENT,
61     TEST_INOUT_NONE,
62     TEST_INOUT_MEM_NO_COPY,
63     TEST_INOUT_MEM_COPY,
64     TEST_INOUT_MEM_FROM_FILE_COPY,
65     TEST_INOUT_MEM_FROM_INEXISTANT_FILE,
66     TEST_INOUT_MEM_FROM_FILE_NO_COPY,
67     TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME,
68     TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART,
69     TEST_INOUT_MEM_FROM_FILE_PART_BY_FP,
70     TEST_OUT_CB,
71     TEST_END
72   } round_t;
73
74 const char *text = "Just GNU it!\n";
75 const char *text2 = "Just GNU it!\nJust GNU it!\n";
76
77 int
78 read_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
79 {
80   static int off = 0;
81   int amount = strlen (text) - off;
82   /*  round_t round = *((round_t *) cb_value);  */
83
84   if (!buffer && !count && !nread)
85     {
86       /* Rewind requested.  */
87       off = 0;
88       return 0;
89     }
90   if (! buffer || !nread)
91     return -1;
92   if (amount <= 0)
93     {
94       /* End of file.  */
95       *nread = 0;
96       return -1;
97     }
98   if (amount > count)
99     amount = count;
100   memcpy (buffer, text, amount);
101   off += amount;
102   *nread = amount;
103   return 0;
104 }
105
106 void
107 read_once_test (round_t round, GpgmeData data)
108 {
109   GpgmeError err;
110   char buffer[1024];
111   size_t read;
112
113   err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
114   fail_if_err (err);
115
116   if (read != strlen (text) || strncmp (buffer, text, strlen (text)))
117     {
118       fprintf (stderr, "%s:%d: (%i) gpgme_data_read returned wrong data\n",
119                __FILE__, __LINE__, round);
120       exit (1);
121     }
122
123   err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
124   if (err != GPGME_EOF)
125     {
126       fprintf (stderr, "%s:%d: (%i) gpgme_data_read did not signal EOF\n",
127                __FILE__, __LINE__, round);
128       exit (1);
129     }
130 }
131
132 void
133 read_test (round_t round, GpgmeData data)
134 {
135   GpgmeError err;
136   char buffer[1024];
137   size_t read;
138
139   if (round == TEST_INOUT_NONE)
140     {
141       err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
142       if (!err)
143         {
144           fprintf (stderr, "%s:%d: (%i) gpgme_data_read succeded unexpectedly\n",
145                    __FILE__, __LINE__, round);
146           exit (1);
147         }
148       return;
149     }
150
151   read_once_test (round, data);
152   err = gpgme_data_rewind (data);
153   fail_if_err (err);
154   read_once_test (round, data);
155 }
156
157 void
158 write_test (round_t round, GpgmeData data)
159 {
160   GpgmeError err;
161   char buffer[1024];
162   size_t read;
163
164   err = gpgme_data_write (data, text, strlen (text));
165   fail_if_err (err);
166
167   read_once_test (round, data);
168   err = gpgme_data_rewind (data);
169   fail_if_err (err);
170
171   if (round == TEST_INOUT_NONE)
172     read_once_test (round, data);
173   else
174     {
175       err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
176       fail_if_err (err);
177
178       if (read != strlen (text2) || strncmp (buffer, text2, strlen (text2)))
179         {
180           fprintf (stderr, "%s:%d: (%i) gpgme_data_read returned wrong data\n",
181                    __FILE__, __LINE__, round);
182           exit (1);
183         }
184
185       err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
186       if (err != GPGME_EOF)
187         {
188           fprintf (stderr, "%s:%d: (%i) gpgme_data_read did not signal EOF\n",
189                    __FILE__, __LINE__, round);
190           exit (1);
191         }
192     }
193 }
194
195 int 
196 main (int argc, char **argv )
197 {
198   round_t round = TEST_INITIALIZER;
199   const char *text_filename = make_filename ("t-data-1.txt");
200   const char *longer_text_filename = make_filename ("t-data-2.txt");
201   const char *missing_filename = "this-file-surely-does-not-exist";
202   GpgmeError err = GPGME_No_Error;
203   GpgmeData data;
204
205   while (++round)
206     {
207       switch (round)
208         {
209         case TEST_INVALID_ARGUMENT:
210           err = gpgme_data_new (NULL);
211           if (!err)
212             {
213               fprintf (stderr, "%s:%d: gpgme_data_new on NULL pointer succeeded "
214                        "unexpectedly\n", __FILE__, __LINE__);
215               exit (1);
216             }
217           if (gpgme_data_get_type (NULL) != GPGME_DATA_TYPE_NONE)
218             {
219               fprintf (stderr, "%s:%d: gpgme_data_get_type on NULL incorrect\n",
220                        __FILE__, __LINE__);
221               exit (1);
222             }
223           continue;
224         case TEST_INOUT_NONE:
225           err = gpgme_data_new (&data);
226           break;
227         case TEST_INOUT_MEM_NO_COPY:
228           err = gpgme_data_new_from_mem (&data, text, strlen (text), 0);
229           break;
230         case TEST_INOUT_MEM_COPY:
231           err = gpgme_data_new_from_mem (&data, text, strlen (text), 1);
232           break;
233         case TEST_INOUT_MEM_FROM_FILE_COPY:
234           err = gpgme_data_new_from_file (&data, text_filename, 1);
235           break;
236         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE:
237           err = gpgme_data_new_from_file (&data, missing_filename, 1);
238           if (!err)
239             {
240               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
241                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
242               exit (1);
243             }
244           continue;
245         case TEST_INOUT_MEM_FROM_FILE_NO_COPY:
246           err = gpgme_data_new_from_file (&data, text_filename, 0);
247           /* This is not implemented yet.  */
248           if (err == GPGME_Not_Implemented)
249             continue;
250           break;
251         case TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME:
252           err = gpgme_data_new_from_filepart (&data, longer_text_filename, 0,
253                                               strlen (text), strlen (text));
254           break;
255         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART:
256           err = gpgme_data_new_from_filepart (&data, missing_filename, 0,
257                                               strlen (text), strlen (text));
258           if (!err)
259             {
260               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
261                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
262               exit (1);
263             }
264           continue;
265         case TEST_INOUT_MEM_FROM_FILE_PART_BY_FP:
266           {
267             FILE *fp = fopen (longer_text_filename, "rb");
268             if (! fp)
269               {
270                 fprintf (stderr, "%s:%d: fopen: %s\n", __FILE__, __LINE__,
271                          strerror (errno));
272                 exit (1);
273               }
274             err = gpgme_data_new_from_filepart (&data, 0, fp,
275                                                 strlen (text), strlen (text));
276           }
277           break;
278         case TEST_OUT_CB:
279           err = gpgme_data_new_with_read_cb (&data, read_cb, &round);
280           break;
281         case TEST_END:
282           return 0;
283         case TEST_INITIALIZER:
284           /* Shouldn't happen.  */
285           fprintf (stderr, "%s:%d: impossible condition\n", __FILE__, __LINE__);
286           exit (1);
287         }
288       fail_if_err (err);
289
290       switch (round)
291         {
292         case TEST_INOUT_NONE:
293           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_NONE)
294             err = GPGME_Invalid_Type;
295           break;
296         case TEST_INOUT_MEM_NO_COPY:
297         case TEST_INOUT_MEM_COPY:
298         case TEST_INOUT_MEM_FROM_FILE_COPY:
299         case TEST_INOUT_MEM_FROM_FILE_NO_COPY:
300         case TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME:
301         case TEST_INOUT_MEM_FROM_FILE_PART_BY_FP:
302           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_MEM)
303             err = GPGME_Invalid_Type;
304           break;
305         case TEST_OUT_CB:
306           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_CB)
307             err = GPGME_Invalid_Type;
308           break;
309         case TEST_INITIALIZER:
310         case TEST_INVALID_ARGUMENT:
311         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE:
312         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART:
313         case TEST_END:
314           /* Shouldn't happen.  */
315           fprintf (stderr, "%s:%d: impossible condition\n", __FILE__, __LINE__);
316           exit (1);
317         }
318       read_test (round, data);
319       if (round != TEST_OUT_CB)
320         write_test (round, data);
321       gpgme_data_release (data);
322     }
323   return 0;
324 }