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