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 strbuf_appendf(&sb, "%s5", "hello");
181 ck_assert_str_eq(sb.buf, "hello5");
182 strbuf_free(&sb);
183 }
184 END_TEST
185
init_suite(void)186 static Suite *init_suite(void)
187 {
188 Suite *s;
189 TCase *tc_core;
190
191 s = suite_create("vrend_strbuf");
192 tc_core = tcase_create("strbuf");
193
194 suite_add_tcase(s, tc_core);
195
196 tcase_add_test(tc_core, strbuf_init);
197 tcase_add_test(tc_core, strbuf_add_small_string);
198 tcase_add_test(tc_core, strbuf_add_small_string_twice);
199 tcase_add_test(tc_core, strbuf_add_large_string);
200 tcase_add_test(tc_core, strbuf_add_huge_string);
201 tcase_add_test(tc_core, strbuf_test_boundary);
202 tcase_add_test(tc_core, strbuf_test_boundary2);
203 tcase_add_test(tc_core, strbuf_test_appendf);
204 tcase_add_test(tc_core, strbuf_test_appendf_str);
205 return s;
206 }
207
main(void)208 int main(void)
209 {
210 Suite *s;
211 SRunner *sr;
212 int number_failed;
213
214 s = init_suite();
215 sr = srunner_create(s);
216
217 srunner_run_all(sr, CK_NORMAL);
218 number_failed = srunner_ntests_failed(sr);
219 srunner_free(sr);
220 return number_failed == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
221 }
222