0877e37c189f1b43f0689be174a65bb4eb75e525
[debian/amanda] / perl / Amanda / Tests.swg
1 /*
2  * Copyright (c) 2008, 2009, 2010 Zmanda, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 as published
6  * by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
10  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
11  * for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16  *
17  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
18  * Sunnyvale, CA 94085, USA, or: http://www.zmanda.com
19  */
20
21 %module "Amanda::Tests"
22 %include "amglue/amglue.swg"
23 %include "exception.i"
24
25 %include "Amanda/Tests.pod"
26
27 %{
28 #include "simpleprng.h"
29 %}
30
31 %inline %{
32
33 /*
34  * exercise bigint.c / integer.swg
35  */
36
37 char *take_guint64(guint64 input) {
38     if (input == G_MAXUINT64) return "MAX";
39     if (input == 0) return "ZERO";
40     return "OTHER";
41 }
42
43 char *take_gint64(gint64 input) {
44     if (input == G_MAXINT64) return "MAX";
45     if (input == G_MININT64) return "MIN";
46     if (input == 0) return "ZERO";
47     return "OTHER";
48 }
49
50 char *take_guint32(guint32 input) {
51     if (input == G_MAXUINT32) return "MAX";
52     if (input == 0) return "ZERO";
53     return "OTHER";
54 }
55
56 char *take_gint32(gint32 input) {
57     if (input == G_MAXINT32) return "MAX";
58     if (input == G_MININT32) return "MIN";
59     if (input == 0) return "ZERO";
60     return "OTHER";
61 }
62
63 char *take_guint16(guint16 input) {
64     if (input == G_MAXUINT16) return "MAX";
65     if (input == 0) return "ZERO";
66     return "OTHER";
67 }
68
69 char *take_gint16(gint16 input) {
70     if (input == G_MAXINT16) return "MAX";
71     if (input == G_MININT16) return "MIN";
72     if (input == 0) return "ZERO";
73     return "OTHER";
74 }
75
76 char *take_guint8(guint8 input) {
77     if (input == G_MAXUINT8) return "MAX";
78     if (input == 0) return "ZERO";
79     return "OTHER";
80 }
81
82 char *take_gint8(gint8 input) {
83     if (input == G_MAXINT8) return "MAX";
84     if (input == G_MININT8) return "MIN";
85     if (input == 0) return "ZERO";
86     return "OTHER";
87 }
88
89
90 guint64 give_guint64(char *input) {
91     if (input[0] == '+') return G_MAXUINT64;
92     return 0;
93 }
94
95 gint64 give_gint64(char *input) {
96     if (input[0] == '-') return G_MININT64;
97     if (input[0] == '+') return G_MAXINT64;
98     return 0;
99 }
100
101 guint32 give_guint32(char *input) {
102     if (input[0] == '+') return G_MAXUINT32;
103     return 0;
104 }
105
106 gint32 give_gint32(char *input) {
107     if (input[0] == '-') return G_MININT32;
108     if (input[0] == '+') return G_MAXINT32;
109     return 0;
110 }
111
112 guint16 give_guint16(char *input) {
113     if (input[0] == '+') return G_MAXUINT16;
114     return 0;
115 }
116
117 gint16 give_gint16(char *input) {
118     if (input[0] == '-') return G_MININT16;
119     if (input[0] == '+') return G_MAXINT16;
120     return 0;
121 }
122
123 guint8 give_guint8(char *input) {
124     if (input[0] == '+') return G_MAXUINT8;
125     return 0;
126 }
127
128 gint8 give_gint8(char *input) {
129     if (input[0] == '-') return G_MININT8;
130     if (input[0] == '+') return G_MAXINT8;
131     return 0;
132 }
133 %}
134
135 /*
136  * Various compiler/system characteristics
137  */
138
139 %inline %{
140
141 int sizeof_size_t(void) {
142     return sizeof(size_t);
143 }
144
145 %}
146
147 /*
148  * simpleprng interface
149  */
150
151 %inline %{
152
153 /* write LENGTH bytes of random data to FILENAME, seeded with SEED */
154 void
155 write_random_file(guint32 seed, size_t length, char *filename) {
156     simpleprng_state_t prng;
157     int fd;
158     char buf[10240];
159
160     simpleprng_seed(&prng, seed);
161
162     fd = open(filename, O_CREAT|O_WRONLY|O_TRUNC, 0666);
163     if (fd < 0)
164         g_critical(_("Could not open test file '%s': %s"), filename, strerror(errno));
165
166     while (length) {
167         size_t to_write = min(sizeof(buf), length);
168         size_t written;
169
170         simpleprng_fill_buffer(&prng, buf, to_write);
171
172         written = full_write(fd, buf, to_write);
173         if (written < to_write)
174             g_critical(_("Error writing test file: %s"), strerror(errno));
175
176         length -= written;
177     }
178
179     close(fd);
180 }
181
182 /* read LENGTH bytes of random data from FILENAME verifying it against
183  * a PRNG seeded with SEED.  Sends any error messages to stderr.
184  *
185  * If check_eof is true, then check that the file is exactly LENGTH bytes long;
186  * otherwise, trailing bytes (such as zero padding from a Device) are ignored.
187  */
188 gboolean
189 verify_random_file(guint32 seed, size_t length, char *filename, gboolean check_eof) {
190     simpleprng_state_t prng;
191     int fd;
192     char buf[10240];
193
194     simpleprng_seed(&prng, seed);
195
196     fd = open(filename, O_RDONLY, 0666);
197     if (fd < 0)
198         g_critical(_("Could not open test file '%s': %s"), filename, strerror(errno));
199
200     while (length) {
201         size_t to_read = min(sizeof(buf), length);
202         size_t bytes_read;
203
204         bytes_read = full_read(fd, buf, to_read);
205         if (bytes_read < to_read) {
206             if (errno) {
207                 g_critical(_("Error reading test file: %s"), strerror(errno));
208             } else {
209                 g_fprintf(stderr, _("Verify of '%s' failed: early EOF with %zd bytes left\n"),
210                         filename, length - bytes_read);
211                 goto error;
212             }
213         }
214
215         if (!simpleprng_verify_buffer(&prng, buf, bytes_read))
216             goto error;
217
218         length -= bytes_read;
219     }
220
221     /* verify that the file contains no extra bytes */
222     if (check_eof) {
223         if (read(fd, buf, 1)) {
224             g_fprintf(stderr, _("Verify of '%s' failed: file is too long\n"), filename);
225             goto error;
226         }
227     }
228
229     close(fd);
230     return TRUE;
231
232 error:
233     close(fd);
234     return FALSE;
235 }
236 %}
237
238 /*
239  * Simple threading test (start a thread and join it)
240  */
241
242 %{
243 static gpointer
244 thread_fn(gpointer data)
245 {
246     guint *d = data;
247     *d = 1;
248     return NULL;
249 }
250 %}
251
252 %inline %{
253 void
254 try_threads(void)
255 {
256     guint data = 0;
257     GThread *thd;
258
259     glib_init();
260
261     thd = g_thread_create(thread_fn, (gpointer)&data, TRUE, NULL);
262     g_thread_join(thd);
263     g_assert(data == 1);
264 }
265 %}