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