2003-09-14 Marcus Brinkmann <marcus@g10code.de>
[gpgme.git] / tests / t-data.c
1 /* t-data - Regression tests for the gpgme_data_t 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) gpgme_error_t " \
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_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   unsigned 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, gpgme_data_t data)
107 {
108   char buffer[1024];
109   size_t read;
110
111   read = gpgme_data_read (data, buffer, sizeof (buffer));
112
113   if (read != strlen (text) || strncmp (buffer, text, strlen (text)))
114     {
115       fprintf (stderr, "%s:%d: (%i) gpgme_data_read returned wrong data\n",
116                __FILE__, __LINE__, round);
117       exit (1);
118     }
119
120   read = gpgme_data_read (data, buffer, sizeof (buffer));
121   if (read)
122     {
123       fprintf (stderr, "%s:%d: (%i) gpgme_data_read did not signal EOF\n",
124                __FILE__, __LINE__, round);
125       exit (1);
126     }
127 }
128
129 void
130 read_test (round_t round, gpgme_data_t data)
131 {
132   char buffer[1024];
133   size_t read;
134
135   if (round == TEST_INOUT_NONE)
136     {
137       read = gpgme_data_read (data, buffer, sizeof (buffer));
138       if (read > 0)
139         {
140           fprintf (stderr, "%s:%d: (%i) gpgme_data_read succeded unexpectedly\n",
141                    __FILE__, __LINE__, round);
142           exit (1);
143         }
144       return;
145     }
146
147   read_once_test (round, data);
148   gpgme_data_seek (data, 0, SEEK_SET);
149   read_once_test (round, data);
150 }
151
152 void
153 write_test (round_t round, gpgme_data_t data)
154 {
155   char buffer[1024];
156   size_t amt;
157
158   amt = gpgme_data_write (data, text, strlen (text));
159   if (amt != strlen (text))
160     fail_if_err (gpg_error_from_errno (errno));
161
162   gpgme_data_seek (data, 0, SEEK_SET);
163
164   if (round == TEST_INOUT_NONE)
165     read_once_test (round, data);
166   else
167     {
168       amt = gpgme_data_read (data, buffer, sizeof (buffer));
169
170       if (amt != strlen (text2) || strncmp (buffer, text2, strlen (text2)))
171         {
172           fprintf (stderr, "%s:%d: (%i) gpgme_data_read returned wrong data\n",
173                    __FILE__, __LINE__, round);
174           exit (1);
175         }
176
177       amt = gpgme_data_read (data, buffer, sizeof (buffer));
178       if (amt)
179         {
180           fprintf (stderr, "%s:%d: (%i) gpgme_data_read did not signal EOF\n",
181                    __FILE__, __LINE__, round);
182           exit (1);
183         }
184     }
185 }
186
187 int 
188 main (int argc, char **argv)
189 {
190   round_t round = TEST_INITIALIZER;
191   const char *text_filename = make_filename ("t-data-1.txt");
192   const char *longer_text_filename = make_filename ("t-data-2.txt");
193   const char *missing_filename = "this-file-surely-does-not-exist";
194   gpgme_error_t err = 0;
195   gpgme_data_t data;
196
197   while (++round)
198     {
199       switch (round)
200         {
201         case TEST_INVALID_ARGUMENT:
202           err = gpgme_data_new (NULL);
203           if (!err)
204             {
205               fprintf (stderr, "%s:%d: gpgme_data_new on NULL pointer succeeded "
206                        "unexpectedly\n", __FILE__, __LINE__);
207               exit (1);
208             }
209           continue;
210         case TEST_INOUT_NONE:
211           err = gpgme_data_new (&data);
212           break;
213         case TEST_INOUT_MEM_NO_COPY:
214           err = gpgme_data_new_from_mem (&data, text, strlen (text), 0);
215           break;
216         case TEST_INOUT_MEM_COPY:
217           err = gpgme_data_new_from_mem (&data, text, strlen (text), 1);
218           break;
219         case TEST_INOUT_MEM_FROM_FILE_COPY:
220           err = gpgme_data_new_from_file (&data, text_filename, 1);
221           break;
222         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE:
223           err = gpgme_data_new_from_file (&data, missing_filename, 1);
224           if (!err)
225             {
226               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
227                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
228               exit (1);
229             }
230           continue;
231         case TEST_INOUT_MEM_FROM_FILE_NO_COPY:
232           err = gpgme_data_new_from_file (&data, text_filename, 0);
233           /* This is not implemented yet.  */
234           if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED
235               || gpg_err_code (err) == GPG_ERR_INV_VALUE)
236             continue;
237           break;
238         case TEST_INOUT_MEM_FROM_FILE_PART_BY_NAME:
239           err = gpgme_data_new_from_filepart (&data, longer_text_filename, 0,
240                                               strlen (text), strlen (text));
241           break;
242         case TEST_INOUT_MEM_FROM_INEXISTANT_FILE_PART:
243           err = gpgme_data_new_from_filepart (&data, missing_filename, 0,
244                                               strlen (text), strlen (text));
245           if (!err)
246             {
247               fprintf (stderr, "%s:%d: gpgme_data_new_from_file on inexistant "
248                        "file succeeded unexpectedly\n", __FILE__, __LINE__);
249               exit (1);
250             }
251           continue;
252         case TEST_INOUT_MEM_FROM_FILE_PART_BY_FP:
253           {
254             FILE *fp = fopen (longer_text_filename, "rb");
255             if (! fp)
256               {
257                 fprintf (stderr, "%s:%d: fopen: %s\n", __FILE__, __LINE__,
258                          strerror (errno));
259                 exit (1);
260               }
261             err = gpgme_data_new_from_filepart (&data, 0, fp,
262                                                 strlen (text), strlen (text));
263           }
264           break;
265         case TEST_END:
266           return 0;
267         case TEST_INITIALIZER:
268           /* Shouldn't happen.  */
269           fprintf (stderr, "%s:%d: impossible condition\n", __FILE__, __LINE__);
270           exit (1);
271         }
272       fail_if_err (err);
273
274       read_test (round, data);
275       write_test (round, data);
276       gpgme_data_release (data);
277     }
278   return 0;
279 }