2001-10-16 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 <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
75 int
76 read_cb (void *cb_value, char *buffer, size_t count, size_t *nread)
77 {
78   static int off = 0;
79   round_t round = *((round_t *) cb_value);
80   int amount = strlen (text) - off;
81
82   if (!buffer && !count && !nread)
83     {
84       /* Rewind requested.  */
85       off = 0;
86       return 0;
87     }
88   if (! buffer || !nread)
89     return -1;
90   if (amount <= 0)
91     {
92       /* End of file.  */
93       *nread = 0;
94       return -1;
95     }
96   if (amount > count)
97     amount = count;
98   memcpy (buffer, text, amount);
99   off += amount;
100   *nread = amount;
101   return 0;
102 }
103
104 void
105 read_once_test (round_t round, GpgmeData data)
106 {
107   GpgmeError err;
108   char buffer[1024];
109   int read;
110
111   err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
112   fail_if_err (err);
113
114   if (read != strlen (text) || strncmp (buffer, text, strlen (text)))
115     {
116       fprintf (stderr, "%s:%d: (%i) gpgme_data_read returned wrong data\n",
117                __FILE__, __LINE__, round);
118       exit (1);
119     }
120
121   err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
122   if (err != GPGME_EOF)
123     {
124       fprintf (stderr, "%s:%d: (%i) gpgme_data_read did not signal EOF\n",
125                __FILE__, __LINE__, round);
126       exit (1);
127     }
128 }
129
130 void
131 read_test (round_t round, GpgmeData data)
132 {
133   GpgmeError err;
134   char buffer[1024];
135   int read;
136
137   if (round == TEST_INOUT_NONE)
138     {
139       err = gpgme_data_read (data, buffer, sizeof (buffer), &read);
140       if (!err)
141         {
142           fprintf (stderr, "%s:%d: (%i) gpgme_data_read succeded unexpectedly\n",
143                    __FILE__, __LINE__, round);
144           exit (1);
145         }
146       return;
147     }
148
149   read_once_test (round, data);
150   err = gpgme_data_rewind (data);
151   fail_if_err (err);
152   read_once_test (round, data);
153 }
154
155 int 
156 main (int argc, char **argv )
157 {
158   round_t round = TEST_INITIALIZER;
159   const char *text_filename = make_filename ("t-data-1.txt");
160   const char *longer_text_filename = make_filename ("t-data-2.txt");
161   const char *missing_filename = "this-file-surely-does-not-exist";
162   GpgmeError err = GPGME_No_Error;
163   GpgmeData data;
164
165   while (++round)
166     {
167       switch (round)
168         {
169         case TEST_INVALID_ARGUMENT:
170           err = gpgme_data_new (NULL);
171           if (!err)
172             {
173               fprintf (stderr, "%s:%d: gpgme_data_new on NULL pointer succeeded "
174                        "unexpectedly\n", __FILE__, __LINE__);
175               exit (1);
176             }
177           if (gpgme_data_get_type (NULL) != GPGME_DATA_TYPE_NONE)
178             {
179               fprintf (stderr, "%s:%d: gpgme_data_get_type on NULL incorrect\n",
180                        __FILE__, __LINE__);
181               exit (1);
182             }
183           continue;
184         case TEST_INOUT_NONE:
185           err = gpgme_data_new (&data);
186           break;
187         case TEST_INOUT_MEM_NO_COPY:
188           err = gpgme_data_new_from_mem (&data, text, strlen (text), 0);
189           break;
190         case TEST_INOUT_MEM_COPY:
191           err = gpgme_data_new_from_mem (&data, text, strlen (text), 1);
192           break;
193         case TEST_INOUT_MEM_FROM_FILE_COPY:
194           err = gpgme_data_new_from_file (&data, text_filename, 1);
195           break;
196         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE:
197           err = gpgme_data_new_from_file (&data, missing_filename, 1);
198           if (!err)
199             {
200               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
201                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
202               exit (1);
203             }
204           continue;
205         case TEST_INOUT_MEM_FROM_FILE_NO_COPY:
206           err = gpgme_data_new_from_file (&data, text_filename, 0);
207           /* This is not implemented yet.  */
208           if (err == GPGME_Not_Implemented)
209             continue;
210           break;
211         case TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME:
212           err = gpgme_data_new_from_filepart (&data, longer_text_filename, 0,
213                                               strlen (text), strlen (text));
214           break;
215         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART:
216           err = gpgme_data_new_from_filepart (&data, missing_filename, 0,
217                                               strlen (text), strlen (text));
218           if (!err)
219             {
220               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
221                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
222               exit (1);
223             }
224           continue;
225         case TEST_INOUT_MEM_FROM_FILE_PART_BY_FP:
226           {
227             FILE *fp = fopen (longer_text_filename, "rb");
228             if (! fp)
229               {
230                 fprintf (stderr, "%s:%d: fopen: %s\n", __FILE__, __LINE__,
231                          strerror (errno));
232                 exit (1);
233               }
234             err = gpgme_data_new_from_filepart (&data, 0, fp,
235                                                 strlen (text), strlen (text));
236           }
237           break;
238         case TEST_OUT_CB:
239           err = gpgme_data_new_with_read_cb (&data, read_cb, &round);
240           break;
241         case TEST_END:
242           return 0;
243         case TEST_INITIALIZER:
244           /* Shouldn't happen.  */
245           fprintf (stderr, "%s:%d: impossible condition\n", __FILE__, __LINE__);
246           exit (1);
247         }
248       fail_if_err (err);
249
250       switch (round)
251         {
252         case TEST_INOUT_NONE:
253           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_NONE)
254             err = GPGME_Invalid_Type;
255           break;
256         case TEST_INOUT_MEM_NO_COPY:
257         case TEST_INOUT_MEM_COPY:
258         case TEST_INOUT_MEM_FROM_FILE_COPY:
259         case TEST_INOUT_MEM_FROM_FILE_NO_COPY:
260         case TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME:
261         case TEST_INOUT_MEM_FROM_FILE_PART_BY_FP:
262           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_MEM)
263             err = GPGME_Invalid_Type;
264           break;
265         case TEST_OUT_CB:
266           if (gpgme_data_get_type (data) != GPGME_DATA_TYPE_CB)
267             err = GPGME_Invalid_Type;
268           break;
269         case TEST_INITIALIZER:
270         case TEST_INVALID_ARGUMENT:
271         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE:
272         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART:
273         case TEST_END:
274           /* Shouldn't happen.  */
275           fprintf (stderr, "%s:%d: impossible condition\n", __FILE__, __LINE__);
276           exit (1);
277         }
278       read_test (round, data);
279
280       gpgme_data_release (data);
281     }
282   return 0;
283 }