1 /*
2 * Copyright © 2020 Google LLC
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * 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 OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <gtest/gtest.h>
25 #include <driconf.h>
26 #include <xmlconfig.h>
27
28 class xmlconfig_test : public ::testing::Test {
29 protected:
30 xmlconfig_test();
31 ~xmlconfig_test();
32
33 driOptionCache drirc_init(const char *driver, const char *drm,
34 const char *exec_name,
35 const char *app, int appver,
36 const char *engine, int enginever);
37
38 driOptionCache options;
39 };
40
xmlconfig_test()41 xmlconfig_test::xmlconfig_test()
42 {
43 /* Unset variables from the envrionment to prevent user settings from
44 * impacting the tests.
45 */
46 unsetenv("glsl_zero_init");
47 unsetenv("always_have_depth_buffer");
48 unsetenv("opt");
49 unsetenv("vblank_mode");
50 unsetenv("not_present");
51 unsetenv("mesa_b_option");
52 unsetenv("mesa_s_option");
53 unsetenv("mest_test_unknown_option");
54 unsetenv("mest_drirc_option");
55
56 options = {};
57 }
58
~xmlconfig_test()59 xmlconfig_test::~xmlconfig_test()
60 {
61 driDestroyOptionInfo(&options);
62 }
63
64 /* wraps a DRI_CONF_OPT_* in the required xml bits */
65 #define DRI_CONF_TEST_OPT(x) x
66
TEST_F(xmlconfig_test,bools)67 TEST_F(xmlconfig_test, bools)
68 {
69 driOptionDescription driconf[] = {
70 DRI_CONF_SECTION_MISCELLANEOUS
71 DRI_CONF_GLSL_ZERO_INIT(false)
72 DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(true)
73 };
74 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
75
76 EXPECT_EQ(driQueryOptionb(&options, "glsl_zero_init"), false);
77 EXPECT_EQ(driQueryOptionb(&options, "always_have_depth_buffer"), true);
78 }
79
TEST_F(xmlconfig_test,ints)80 TEST_F(xmlconfig_test, ints)
81 {
82 driOptionDescription driconf[] = {
83 DRI_CONF_SECTION_MISCELLANEOUS
84 DRI_CONF_OPT_I(opt, 2, 0, 999, "option")
85 };
86 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
87
88 EXPECT_EQ(driQueryOptioni(&options, "opt"), 2);
89 }
90
TEST_F(xmlconfig_test,floats)91 TEST_F(xmlconfig_test, floats)
92 {
93 driOptionDescription driconf[] = {
94 DRI_CONF_SECTION_MISCELLANEOUS
95 DRI_CONF_OPT_F(opt, 2.0, 1.0, 2.0, "option")
96 };
97 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
98
99 EXPECT_EQ(driQueryOptionf(&options, "opt"), 2.0);
100 }
101
TEST_F(xmlconfig_test,enums)102 TEST_F(xmlconfig_test, enums)
103 {
104 driOptionDescription driconf[] = {
105 DRI_CONF_SECTION_MISCELLANEOUS
106 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
107 };
108 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
109
110 EXPECT_EQ(driQueryOptioni(&options, "vblank_mode"), DRI_CONF_VBLANK_DEF_INTERVAL_1);
111 }
112
TEST_F(xmlconfig_test,enums_from_env)113 TEST_F(xmlconfig_test, enums_from_env)
114 {
115 driOptionDescription driconf[] = {
116 DRI_CONF_SECTION_MISCELLANEOUS
117 DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_1)
118 };
119
120 setenv("vblank_mode", "0", 1);
121 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
122
123 EXPECT_EQ(0, driQueryOptioni(&options, "vblank_mode"));
124 }
125
TEST_F(xmlconfig_test,string)126 TEST_F(xmlconfig_test, string)
127 {
128 driOptionDescription driconf[] = {
129 DRI_CONF_SECTION_MISCELLANEOUS
130 DRI_CONF_OPT_S(opt, value, "option")
131 };
132 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
133
134 EXPECT_STREQ(driQueryOptionstr(&options, "opt"), "value");
135 }
136
TEST_F(xmlconfig_test,check_option)137 TEST_F(xmlconfig_test, check_option)
138 {
139 driOptionDescription driconf[] = {
140 DRI_CONF_SECTION_MISCELLANEOUS
141 DRI_CONF_GLSL_ZERO_INIT(true)
142 DRI_CONF_ALWAYS_HAVE_DEPTH_BUFFER(true)
143 };
144 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
145
146 EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_BOOL), true);
147
148 EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_ENUM), false);
149 EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_INT), false);
150 EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_FLOAT), false);
151 EXPECT_EQ(driCheckOption(&options, "glsl_zero_init", DRI_STRING), false);
152
153 EXPECT_EQ(driCheckOption(&options, "not_present", DRI_BOOL), false);
154 }
155
TEST_F(xmlconfig_test,copy_cache)156 TEST_F(xmlconfig_test, copy_cache)
157 {
158 driOptionDescription driconf[] = {
159 DRI_CONF_SECTION_MISCELLANEOUS
160 DRI_CONF_OPT_B(mesa_b_option, true, "description")
161 DRI_CONF_OPT_S(mesa_s_option, value, "description")
162 };
163 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
164
165 driOptionCache cache;
166
167 /* This tries to parse user config files. We've called our option
168 * "mesa_test_option" so the test shouldn't end up with something from the
169 * user's homedir/environment that would override us.
170 */
171 driParseConfigFiles(&cache, &options,
172 0, "driver", "drm", NULL,
173 NULL, 0,
174 NULL, 0);
175
176 /* Can we inspect the cache? */
177 EXPECT_EQ(driCheckOption(&cache, "mesa_b_option", DRI_BOOL), true);
178 EXPECT_EQ(driCheckOption(&cache, "mesa_s_option", DRI_STRING), true);
179 EXPECT_EQ(driCheckOption(&cache, "mesa_test_unknown_option", DRI_BOOL), false);
180
181 /* Did the value get copied? */
182 EXPECT_EQ(driQueryOptionb(&cache, "mesa_b_option"), true);
183 EXPECT_STREQ(driQueryOptionstr(&cache, "mesa_s_option"), "value");
184
185 driDestroyOptionCache(&cache);
186 }
187
188 driOptionCache
drirc_init(const char * driver,const char * drm,const char * exec_name,const char * app,int appver,const char * engine,int enginever)189 xmlconfig_test::drirc_init(const char *driver, const char *drm,
190 const char *exec_name,
191 const char *app, int appver,
192 const char *engine, int enginever)
193 {
194 /* Make the parser look in the directory of config files for the test,
195 * passed in by meson.build.
196 */
197 driInjectDataDir(getenv("DRIRC_CONFIGDIR"));
198
199 driInjectExecName(exec_name);
200
201 driOptionDescription driconf[] = {
202 DRI_CONF_SECTION_MISCELLANEOUS
203 DRI_CONF_OPT_I(mesa_drirc_option, 0, 0, 200, "description")
204 };
205 driParseOptionInfo(&options, driconf, ARRAY_SIZE(driconf));
206
207 driOptionCache cache;
208
209 /* This should parse the "user" drirc files under ./tests/drirc_test/,
210 * based on the setting of $HOME by meson.build.
211 */
212 driParseConfigFiles(&cache, &options,
213 0, driver, drm, NULL,
214 app, appver,
215 engine, enginever);
216
217 return cache;
218 }
219
TEST_F(xmlconfig_test,drirc_app)220 TEST_F(xmlconfig_test, drirc_app)
221 {
222 driOptionCache cache = drirc_init("driver", "drm",
223 "app1",
224 NULL, 0,
225 NULL, 0);
226 #if WITH_XMLCONFIG
227 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 1);
228 #else
229 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 0);
230 #endif
231 driDestroyOptionCache(&cache);
232 }
233
TEST_F(xmlconfig_test,drirc_user_app)234 TEST_F(xmlconfig_test, drirc_user_app)
235 {
236 driOptionCache cache = drirc_init("driver", "drm",
237 "app3",
238 NULL, 0,
239 NULL, 0);
240 #if WITH_XMLCONFIG
241 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 10);
242 #else
243 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 0);
244 #endif
245 driDestroyOptionCache(&cache);
246 }
247
TEST_F(xmlconfig_test,drirc_env_override)248 TEST_F(xmlconfig_test, drirc_env_override)
249 {
250 setenv("mesa_drirc_option", "7", 1);
251 driOptionCache cache = drirc_init("driver", "drm",
252 "app1",
253 NULL, 0,
254 NULL, 0);
255 /* env var takes precedence over config files */
256 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 7);
257 unsetenv("mesa_drirc_option");
258 driDestroyOptionCache(&cache);
259 }
260
261 #if WITH_XMLCONFIG
TEST_F(xmlconfig_test,drirc_app_versioned)262 TEST_F(xmlconfig_test, drirc_app_versioned)
263 {
264 driOptionCache cache = drirc_init("driver", "drm",
265 NULL,
266 "Versioned App Name", 1,
267 NULL, 0);
268 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 3);
269 driDestroyOptionCache(&cache);
270 }
271
TEST_F(xmlconfig_test,drirc_engine_versioned)272 TEST_F(xmlconfig_test, drirc_engine_versioned)
273 {
274 driOptionCache cache = drirc_init("driver", "drm",
275 NULL,
276 "unknownapp", 0,
277 "Versioned Engine Name", 1);
278 EXPECT_EQ(driQueryOptioni(&cache, "mesa_drirc_option"), 5);
279 driDestroyOptionCache(&cache);
280 }
281 #endif
282