1 /**
2 * collectd - src/utils_config_cores_test.c
3 *
4 * Copyright(c) 2018 Intel Corporation. All rights reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * Authors:
25 * Kamil Wiatrowski <kamilx.wiatrowski@intel.com>
26 **/
27
28 #include "collectd.h"
29
30 #include "testing.h"
31 #include "utils/config_cores/config_cores.c" /* sic */
32
33 oconfig_value_t test_cfg_values[] = {{{"0"}, OCONFIG_TYPE_STRING},
34 {{"1-2"}, OCONFIG_TYPE_STRING},
35 {{"[3-4]"}, OCONFIG_TYPE_STRING}};
36
37 oconfig_item_t test_cfg = {
38 "Cores", test_cfg_values, STATIC_ARRAY_SIZE(test_cfg_values), NULL, NULL,
39 0};
40
compare_with_test_config(core_groups_list_t * cgl)41 static int compare_with_test_config(core_groups_list_t *cgl) {
42 if (cgl->num_cgroups == 4 && cgl->cgroups[0].num_cores == 1 &&
43 strcmp("0", cgl->cgroups[0].desc) == 0 && cgl->cgroups[0].cores[0] == 0 &&
44 cgl->cgroups[1].num_cores == 2 &&
45 strcmp("1-2", cgl->cgroups[1].desc) == 0 &&
46 cgl->cgroups[1].cores[0] == 1 && cgl->cgroups[1].cores[1] == 2 &&
47 cgl->cgroups[2].num_cores == 1 &&
48 strcmp("3", cgl->cgroups[2].desc) == 0 && cgl->cgroups[2].cores[0] == 3 &&
49 cgl->cgroups[3].num_cores == 1 &&
50 strcmp("4", cgl->cgroups[3].desc) == 0 && cgl->cgroups[3].cores[0] == 4)
51 return 0;
52
53 return -1;
54 }
55
DEF_TEST(string_to_uint)56 DEF_TEST(string_to_uint) {
57 int ret = 0;
58 char *s = "13", *s1 = "0xd", *s2 = "g";
59 unsigned n = 0;
60
61 ret = str_to_uint(s, &n);
62 EXPECT_EQ_INT(0, ret);
63 EXPECT_EQ_INT(13, n);
64
65 ret = str_to_uint(s1, &n);
66 EXPECT_EQ_INT(0, ret);
67 EXPECT_EQ_INT(13, n);
68
69 ret = str_to_uint(s2, &n);
70 OK(ret < 0);
71
72 ret = str_to_uint(NULL, &n);
73 OK(ret < 0);
74 return 0;
75 }
76
DEF_TEST(cores_list_to_numbers)77 DEF_TEST(cores_list_to_numbers) {
78 size_t n = 0;
79 unsigned nums[MAX_CORES];
80 char str[64] = "";
81
82 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
83 EXPECT_EQ_INT(0, n);
84
85 strncpy(str, "1", STATIC_ARRAY_SIZE(str));
86 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
87 EXPECT_EQ_INT(1, n);
88 EXPECT_EQ_INT(1, nums[0]);
89
90 strncpy(str, "0,2-3", STATIC_ARRAY_SIZE(str));
91 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
92 EXPECT_EQ_INT(3, n);
93 EXPECT_EQ_INT(0, nums[0]);
94 EXPECT_EQ_INT(2, nums[1]);
95 EXPECT_EQ_INT(3, nums[2]);
96
97 strncpy(str, "11-0xa", STATIC_ARRAY_SIZE(str));
98 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
99 EXPECT_EQ_INT(2, n);
100 EXPECT_EQ_INT(10, nums[0]);
101 EXPECT_EQ_INT(11, nums[1]);
102
103 snprintf(str, sizeof(str), "0-%d", (MAX_CORES - 1));
104 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
105 EXPECT_EQ_INT(MAX_CORES, n);
106 EXPECT_EQ_INT(0, nums[0]);
107 EXPECT_EQ_INT(MAX_CORES - 1, nums[MAX_CORES - 1]);
108
109 /* Should return 0 for incorrect syntax. */
110 strncpy(str, "5g", STATIC_ARRAY_SIZE(str));
111 n = str_list_to_nums(str, nums, STATIC_ARRAY_SIZE(nums));
112 EXPECT_EQ_INT(0, n);
113 return 0;
114 }
115
DEF_TEST(check_grouped_cores)116 DEF_TEST(check_grouped_cores) {
117 int ret = 0;
118 _Bool grouped;
119 char src[64] = "[5-15]";
120 char dest[64];
121
122 ret = check_core_grouping(dest, src, sizeof(dest), &grouped);
123 EXPECT_EQ_INT(0, ret);
124 EXPECT_EQ_INT(0, grouped);
125 EXPECT_EQ_STR("5-15", dest);
126
127 strncpy(src, " 5-15", STATIC_ARRAY_SIZE(src));
128 ret = check_core_grouping(dest, src, sizeof(dest), &grouped);
129 EXPECT_EQ_INT(0, ret);
130 EXPECT_EQ_INT(1, grouped);
131 EXPECT_EQ_STR("5-15", dest);
132 return 0;
133 }
134
DEF_TEST(cores_option_parse)135 DEF_TEST(cores_option_parse) {
136 int ret = 0;
137 core_groups_list_t cgl = {0};
138
139 ret = config_cores_parse(&test_cfg, &cgl);
140 EXPECT_EQ_INT(0, ret);
141 CHECK_NOT_NULL(cgl.cgroups);
142 EXPECT_EQ_INT(0, compare_with_test_config(&cgl));
143
144 config_cores_cleanup(&cgl);
145 return 0;
146 }
147
DEF_TEST(cores_option_parse_fail)148 DEF_TEST(cores_option_parse_fail) {
149 int ret = 0;
150 core_groups_list_t cgl = {0};
151 /* Wrong value, missing closing bracket ] */
152 oconfig_value_t values = {{"[0-15"}, OCONFIG_TYPE_STRING};
153 oconfig_item_t cfg = {"Cores", &values, 1, NULL, NULL, 0};
154
155 ret = config_cores_parse(&cfg, &cgl);
156 EXPECT_EQ_INT(-EINVAL, ret);
157 EXPECT_EQ_INT(0, cgl.num_cgroups);
158 OK(NULL == cgl.cgroups);
159 return 0;
160 }
161
DEF_TEST(cores_default_list)162 DEF_TEST(cores_default_list) {
163 int ret = 0;
164 core_groups_list_t cgl = {0};
165
166 ret = config_cores_default(2, &cgl);
167 EXPECT_EQ_INT(0, ret);
168 EXPECT_EQ_INT(2, cgl.num_cgroups);
169 CHECK_NOT_NULL(cgl.cgroups);
170
171 CHECK_NOT_NULL(cgl.cgroups[0].cores);
172 CHECK_NOT_NULL(cgl.cgroups[0].desc);
173 EXPECT_EQ_STR("0", cgl.cgroups[0].desc);
174 EXPECT_EQ_INT(1, cgl.cgroups[0].num_cores);
175 EXPECT_EQ_INT(0, cgl.cgroups[0].cores[0]);
176
177 CHECK_NOT_NULL(cgl.cgroups[1].cores);
178 CHECK_NOT_NULL(cgl.cgroups[1].desc);
179 EXPECT_EQ_STR("1", cgl.cgroups[1].desc);
180 EXPECT_EQ_INT(1, cgl.cgroups[1].num_cores);
181 EXPECT_EQ_INT(1, cgl.cgroups[1].cores[0]);
182
183 config_cores_cleanup(&cgl);
184 return 0;
185 }
186
DEF_TEST(cores_default_list_fail)187 DEF_TEST(cores_default_list_fail) {
188 int ret = 0;
189 core_groups_list_t cgl = {0};
190
191 ret = config_cores_default(-1, &cgl);
192 OK(ret < 0);
193 ret = config_cores_default(MAX_CORES + 1, &cgl);
194 OK(ret < 0);
195 ret = config_cores_default(1, NULL);
196 OK(ret < 0);
197 return 0;
198 }
199
DEF_TEST(cores_group_cleanup)200 DEF_TEST(cores_group_cleanup) {
201 core_groups_list_t cgl;
202 cgl.cgroups = calloc(1, sizeof(*cgl.cgroups));
203 CHECK_NOT_NULL(cgl.cgroups);
204 cgl.num_cgroups = 1;
205 cgl.cgroups[0].desc = strdup("1");
206 cgl.cgroups[0].cores = calloc(1, sizeof(*cgl.cgroups[0].cores));
207 CHECK_NOT_NULL(cgl.cgroups[0].cores);
208 cgl.cgroups[0].cores[0] = 1;
209 cgl.cgroups[0].num_cores = 1;
210
211 config_cores_cleanup(&cgl);
212 OK(NULL == cgl.cgroups);
213 EXPECT_EQ_INT(0, cgl.num_cgroups);
214 return 0;
215 }
216
DEF_TEST(cores_group_cmp)217 DEF_TEST(cores_group_cmp) {
218 unsigned cores_mock[] = {0, 1, 2};
219 core_group_t group_mock = {"0,1,2", cores_mock, 3};
220 unsigned cores_mock_2[] = {2, 3};
221 core_group_t group_mock_2 = {"2,3", cores_mock_2, 2};
222
223 int ret = config_cores_cmp_cgroups(&group_mock, &group_mock);
224 EXPECT_EQ_INT(1, ret);
225
226 ret = config_cores_cmp_cgroups(&group_mock, &group_mock_2);
227 EXPECT_EQ_INT(-1, ret);
228
229 cores_mock_2[0] = 4;
230 ret = config_cores_cmp_cgroups(&group_mock, &group_mock_2);
231 EXPECT_EQ_INT(0, ret);
232 return 0;
233 }
234
main(void)235 int main(void) {
236 RUN_TEST(string_to_uint);
237 RUN_TEST(cores_list_to_numbers);
238 RUN_TEST(check_grouped_cores);
239
240 RUN_TEST(cores_group_cleanup);
241 RUN_TEST(cores_option_parse);
242 RUN_TEST(cores_option_parse_fail);
243 RUN_TEST(cores_default_list);
244 RUN_TEST(cores_default_list_fail);
245
246 RUN_TEST(cores_group_cmp);
247
248 END_TEST;
249 }
250