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