1 /**************************************************************************
2 *
3 * Copyright (C) 2019 Red Hat Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included
13 * in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21 * OTHER DEALINGS IN THE SOFTWARE.
22 *
23 **************************************************************************/
24 #include <check.h>
25 #include <stdio.h>
26 #include "../src/vrend_strbuf.h"
27
28 /* Test the vrend strbuf implementation */
29
START_TEST(strbuf_init)30 START_TEST(strbuf_init)
31 {
32 struct vrend_strbuf sb;
33 bool ret;
34 ret = strbuf_alloc(&sb, 1024);
35 ck_assert_int_eq(ret, true);
36 ck_assert_int_eq(sb.alloc_size, 1024);
37 strbuf_free(&sb);
38 }
39 END_TEST
40
START_TEST(strbuf_add_small_string)41 START_TEST(strbuf_add_small_string)
42 {
43 struct vrend_strbuf sb;
44 bool ret;
45 char str[27];
46 ret = strbuf_alloc(&sb, 1024);
47 ck_assert_int_eq(ret, true);
48
49 for (int i = 0; i < 26; i++)
50 str[i] = 'a' + i;
51 str[26] = 0;
52 strbuf_append(&sb, str);
53 ck_assert_int_eq(strbuf_get_error(&sb), false);
54 ck_assert_int_eq(sb.size, strlen(sb.buf));
55 strbuf_free(&sb);
56 }
57 END_TEST
58
START_TEST(strbuf_add_small_string_twice)59 START_TEST(strbuf_add_small_string_twice)
60 {
61 struct vrend_strbuf sb;
62 bool ret;
63 char str[27];
64 ret = strbuf_alloc(&sb, 1024);
65 ck_assert_int_eq(ret, true);
66
67 for (int i = 0; i < 26; i++)
68 str[i] = 'a' + i;
69 str[26] = 0;
70 strbuf_append(&sb, str);
71 strbuf_append(&sb, str);
72 ck_assert_int_eq(strbuf_get_error(&sb), false);
73 ck_assert_int_eq(strbuf_get_len(&sb), strlen(sb.buf));
74 strbuf_free(&sb);
75 }
76 END_TEST
77
START_TEST(strbuf_add_large_string)78 START_TEST(strbuf_add_large_string)
79 {
80 struct vrend_strbuf sb;
81 bool ret;
82 char str[256];
83 ret = strbuf_alloc(&sb, 128);
84 ck_assert_int_eq(ret, true);
85
86 for (int i = 0; i < 255; i++)
87 str[i] = 'a' + (i % 26);
88 str[255] = 0;
89 strbuf_append(&sb, str);
90
91 ck_assert_int_eq(strbuf_get_error(&sb), false);
92 ck_assert_int_eq(strbuf_get_len(&sb), strlen(sb.buf));
93 ck_assert_int_eq(sb.alloc_size, 128 + STRBUF_MIN_MALLOC);
94 strbuf_free(&sb);
95 }
96 END_TEST
97
START_TEST(strbuf_add_huge_string)98 START_TEST(strbuf_add_huge_string)
99 {
100 struct vrend_strbuf sb;
101 bool ret;
102 char str[2048];
103 ret = strbuf_alloc(&sb, 128);
104 ck_assert_int_eq(ret, true);
105
106 for (int i = 0; i < 2047; i++)
107 str[i] = 'a' + (i % 26);
108 str[2047] = 0;
109 strbuf_append(&sb, str);
110
111 ck_assert_int_eq(strbuf_get_error(&sb), false);
112 ck_assert_int_eq(strbuf_get_len(&sb), strlen(sb.buf));
113 ck_assert_int_eq(sb.alloc_size, 2048);
114 ck_assert_int_ge(sb.alloc_size, strbuf_get_len(&sb) + 1);
115 strbuf_free(&sb);
116 }
117 END_TEST
118
START_TEST(strbuf_test_boundary)119 START_TEST(strbuf_test_boundary)
120 {
121 struct vrend_strbuf sb;
122 bool ret;
123 char str[128];
124 ret = strbuf_alloc(&sb, 128);
125 ck_assert_int_eq(ret, true);
126
127 for (int i = 0; i < 127; i++)
128 str[i] = 'a' + (i % 26);
129 str[127] = 0;
130 strbuf_append(&sb, str);
131 ck_assert_int_eq(strbuf_get_error(&sb), false);
132 ck_assert_int_eq(strbuf_get_len(&sb), strlen(sb.buf));
133 ck_assert_int_eq(sb.alloc_size, 128);
134 ck_assert_int_ge(sb.alloc_size, strbuf_get_len(&sb) + 1);
135 strbuf_free(&sb);
136 }
137 END_TEST
138
START_TEST(strbuf_test_boundary2)139 START_TEST(strbuf_test_boundary2)
140 {
141 struct vrend_strbuf sb;
142 bool ret;
143 char str[513];
144 ret = strbuf_alloc(&sb, 1024);
145 ck_assert_int_eq(ret, true);
146
147 for (int i = 0; i < 512; i++)
148 str[i] = 'a' + (i % 26);
149 str[512] = 0;
150 strbuf_append(&sb, str);
151 strbuf_append(&sb, str);
152 ck_assert_int_eq(strbuf_get_error(&sb), false);
153 ck_assert_int_eq(strbuf_get_len(&sb), strlen(sb.buf));
154 /* we should have 512 + 512 + 1 at least */
155 ck_assert_int_ge(sb.alloc_size, strbuf_get_len(&sb) + 1);
156 ck_assert_int_gt(sb.alloc_size, 1024);
157
158 strbuf_free(&sb);
159 }
160 END_TEST
161
START_TEST(strbuf_test_appendf)162 START_TEST(strbuf_test_appendf)
163 {
164 struct vrend_strbuf sb;
165 bool ret;
166 ret = strbuf_alloc(&sb, 1024);
167 ck_assert_int_eq(ret, true);
168 strbuf_appendf(&sb, "%d", 5);
169 ck_assert_str_eq(sb.buf, "5");
170 strbuf_free(&sb);
171 }
172 END_TEST
173
START_TEST(strbuf_test_appendf_str)174 START_TEST(strbuf_test_appendf_str)
175 {
176 struct vrend_strbuf sb;
177 bool ret;
178 ret = strbuf_alloc(&sb, 1024);
179 ck_assert_int_eq(ret, true);
180 ck_assert_int_eq(sb.external_buffer, false);
181 strbuf_appendf(&sb, "%s5", "hello");
182 ck_assert_str_eq(sb.buf, "hello5");
183 strbuf_free(&sb);
184 }
185 END_TEST
186
187
START_TEST(strbuf_test_fixed_string)188 START_TEST(strbuf_test_fixed_string)
189 {
190 struct vrend_strbuf sb;
191 bool ret;
192 char buf[1024];
193 ret = strbuf_alloc_fixed(&sb, buf, 1024);
194 ck_assert_int_eq(ret, true);
195 ck_assert_int_eq(sb.external_buffer, true);
196 strbuf_appendf(&sb, "%s5", "hello");
197 ck_assert_str_eq(sb.buf, "hello5");
198 strbuf_free(&sb);
199 }
200 END_TEST
201
202
init_suite(void)203 static Suite *init_suite(void)
204 {
205 Suite *s;
206 TCase *tc_core;
207
208 s = suite_create("vrend_strbuf");
209 tc_core = tcase_create("strbuf");
210
211 suite_add_tcase(s, tc_core);
212
213 tcase_add_test(tc_core, strbuf_init);
214 tcase_add_test(tc_core, strbuf_add_small_string);
215 tcase_add_test(tc_core, strbuf_add_small_string_twice);
216 tcase_add_test(tc_core, strbuf_add_large_string);
217 tcase_add_test(tc_core, strbuf_add_huge_string);
218 tcase_add_test(tc_core, strbuf_test_boundary);
219 tcase_add_test(tc_core, strbuf_test_boundary2);
220 tcase_add_test(tc_core, strbuf_test_appendf);
221 tcase_add_test(tc_core, strbuf_test_appendf_str);
222 tcase_add_test(tc_core, strbuf_test_fixed_string);
223 return s;
224 }
225
main(void)226 int main(void)
227 {
228 Suite *s;
229 SRunner *sr;
230 int number_failed;
231
232 s = init_suite();
233 sr = srunner_create(s);
234
235 srunner_run_all(sr, CK_NORMAL);
236 number_failed = srunner_ntests_failed(sr);
237 srunner_free(sr);
238 return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
239 }
240