Imported Upstream version 3.3.3
[debian/amanda] / common-src / hexencode-test.c
1 /*
2  * Copyright (c) Zmanda Inc.  All Rights Reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
12  * License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public License
15  * along with this library; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA.
17  *
18  * Contact information: Zmanda Inc., 465 S. Mathilda Ave., Suite 300
19  * Sunnyvale, CA 94086, USA, or: http://www.zmanda.com
20  */
21
22 #include "amanda.h"
23 #include "util.h"
24 #include "testutils.h"
25 #include "simpleprng.h"
26
27 static gboolean test_encode(void);
28 static gboolean test_decode(void);
29 static gboolean test_roundtrip(void);
30 static gboolean test_roundtrip_rand(void);
31
32 typedef struct {char *in; char *out;} enc_vec;
33 static gboolean
34 test_encode(void)
35 {
36     static const enc_vec test_strs[] = {
37         {"hi", "hi"},
38         {"hi!", "hi%21"},
39         {"%", "%25"},
40         {"*", "%2a"},
41         {"\n", "%0a"},
42         {"\nhi\n", "%0ahi%0a"}
43     };
44     static const int num = sizeof(test_strs)/sizeof(enc_vec);
45     int i;
46     gboolean ret;
47     char *tmp;
48     
49     ret = TRUE;
50     for (i = 0; i < num; i++) {
51         tmp = hexencode_string(test_strs[i].in);
52         if (!tmp || strcmp(test_strs[i].out, tmp)) {
53             ret = FALSE;
54             tu_dbg("encode failure:\n")
55             tu_dbg("input:    \"%s\"\n", test_strs[i].in);
56             tu_dbg("output:   \"%s\"\n", tmp? tmp : "(null)");
57             tu_dbg("expected: \"%s\"\n", test_strs[i].out);
58         }
59         g_free(tmp);
60     }
61     return ret;
62 }
63
64 typedef struct {char *in; char *out; gboolean expect_err; } dec_vec;
65 static gboolean
66 test_decode(void)
67 {
68     static const dec_vec test_strs[] = {
69         {"hi", "hi", FALSE},
70         {"hi%21", "hi!", FALSE},
71         {"%25", "%", FALSE},
72         {"%2a", "*", FALSE},
73         {"%2A", "*", FALSE},
74         {"%0a", "\n", FALSE},
75         {"%0A", "\n", FALSE},
76         {"%0ahi%0a", "\nhi\n", FALSE},
77         {"%", "", TRUE},
78         {"%2", "", TRUE},
79         {"h%", "", TRUE},
80         {"%0h", "", TRUE},
81         {"%h0", "", TRUE},
82         {"%00", "", TRUE}
83     };
84     static const int num = sizeof(test_strs)/sizeof(dec_vec);
85     int i;
86     gboolean ret;
87     char *tmp;
88     GError *err = NULL;
89     
90     ret = TRUE;
91     for (i = 0; i < num; i++) {
92         tmp = hexdecode_string(test_strs[i].in, &err);
93         if (!tmp || strcmp(test_strs[i].out, tmp) ||
94             (!!err != test_strs[i].expect_err)) {
95             ret = FALSE;
96             tu_dbg("decode failure:\n")
97             tu_dbg("input:     \"%s\"\n", test_strs[i].in);
98             tu_dbg("output:    \"%s\"\n", tmp? tmp : "(null)");
99             tu_dbg("expected:  \"%s\"\n", test_strs[i].out);
100             tu_dbg("error msg: %s\n", err? err->message : "(none)");
101         }
102         g_clear_error(&err);
103         g_free(tmp);
104             
105     }
106     return ret;
107 }
108
109 typedef char* round_vec;
110 static gboolean
111 test_roundtrip(void)
112 {
113     static const round_vec test_strs[] = {
114         "hi",
115         "hi!",
116         "hi%21",
117         "%",
118         "*",
119         "\n",
120         "h%"
121     };
122     static const int num = sizeof(test_strs)/sizeof(round_vec);
123     int i;
124     gboolean ret;
125     char *tmp_enc = NULL, *tmp_dec = NULL;
126     GError *err = NULL;
127     
128     ret = TRUE;
129     for (i = 0; i < num; i++) {
130         tmp_enc = hexencode_string(test_strs[i]);
131         tmp_dec = tmp_enc? hexdecode_string(tmp_enc, &err) : NULL;
132         if (!tmp_enc || !tmp_dec || strcmp(test_strs[i], tmp_dec) || err) {
133             ret = FALSE;
134             tu_dbg("roundtrip failure:\n")
135             tu_dbg("input:      \"%s\"\n", test_strs[i]);
136             tu_dbg("enc output: \"%s\"\n", tmp_enc? tmp_enc : "(null)");
137             tu_dbg("dec output: \"%s\"\n", tmp_dec? tmp_dec : "(null)");
138             tu_dbg("error msg:  %s\n", err? err->message : "(none)");
139         }
140         g_clear_error(&err);
141         amfree(tmp_enc);
142         amfree(tmp_dec);
143     }
144     return ret;
145 }
146
147 static gboolean
148 test_roundtrip_rand(void)
149 {
150     int i;
151     gboolean ret;
152     simpleprng_state_t state;
153     char *in, *tmp_enc = NULL, *tmp_dec = NULL;
154     size_t size;
155     GError *err = NULL;
156     
157     simpleprng_seed(&state, 0xface);
158     ret = TRUE;
159     for (i = 0; i < 100; i++) {
160         size = simpleprng_rand_byte(&state);
161         in = g_malloc0(size+1);
162         simpleprng_fill_buffer(&state, in, size);
163         tmp_enc = hexencode_string(in);
164         tmp_dec = tmp_enc? hexdecode_string(tmp_enc, &err) : NULL;
165         if (!tmp_enc || !tmp_dec || strcmp(in, tmp_dec) || err) {
166             ret = FALSE;
167             tu_dbg("roundtrip failure:\n")
168             tu_dbg("input:      \"%s\"\n", in);
169             tu_dbg("enc output: \"%s\"\n", tmp_enc? tmp_enc : "(null)");
170             tu_dbg("dec output: \"%s\"\n", tmp_dec? tmp_dec : "(null)");
171             tu_dbg("error msg:  %s\n", err? err->message : "(none)");
172         }
173         g_clear_error(&err);
174         amfree(tmp_enc);
175         amfree(tmp_dec);
176         g_free(in);
177     }
178     return ret;
179 }
180
181 int
182 main(int argc, char **argv)
183 {
184     static TestUtilsTest tests[] = {
185         TU_TEST(test_encode, 90),
186         TU_TEST(test_decode, 90),
187         TU_TEST(test_roundtrip, 90),
188         TU_TEST(test_roundtrip_rand, 90),
189         TU_END()
190     };
191     return testutils_run_tests(argc, argv, tests);
192 }