]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-env-util.c
basic: support default and alternate values for env expansion
[thirdparty/systemd.git] / src / test / test-env-util.c
CommitLineData
c24eb49e
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
b8c83cfc 5 Copyright 2016 Zbigniew Jędrzejewski-Szmek
c24eb49e
LP
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
c24eb49e
LP
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 15 Lesser General Public License for more details.
c24eb49e 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
c24eb49e
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
c24eb49e
LP
21#include <string.h>
22
4d1a6904 23#include "env-util.h"
07630cea
LP
24#include "string-util.h"
25#include "strv.h"
26#include "util.h"
c24eb49e 27
940bd473
TA
28static void test_strv_env_delete(void) {
29 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
30
31 a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL);
9b5d6bd9
LP
32 assert_se(a);
33
940bd473 34 b = strv_new("PIEP", "FOO", NULL);
9b5d6bd9
LP
35 assert_se(b);
36
940bd473 37 c = strv_new("SCHLUMPF", NULL);
9b5d6bd9 38 assert_se(c);
940bd473
TA
39
40 d = strv_env_delete(a, 2, b, c);
9b5d6bd9 41 assert_se(d);
940bd473 42
9b5d6bd9
LP
43 assert_se(streq(d[0], "WALDO=WALDO"));
44 assert_se(streq(d[1], "WALDO="));
45 assert_se(strv_length(d) == 2);
940bd473
TA
46}
47
6162512c
RS
48static void test_strv_env_get(void) {
49 char **l;
50
51 l = STRV_MAKE("ONE_OR_TWO=1", "THREE=3", "ONE_OR_TWO=2", "FOUR=4");
52
53 assert_se(streq(strv_env_get(l, "ONE_OR_TWO"), "2"));
54 assert_se(streq(strv_env_get(l, "THREE"), "3"));
55 assert_se(streq(strv_env_get(l, "FOUR"), "4"));
56}
57
940bd473
TA
58static void test_strv_env_unset(void) {
59 _cleanup_strv_free_ char **l = NULL;
60
61 l = strv_new("PIEP", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
9b5d6bd9 62 assert_se(l);
940bd473 63
9b5d6bd9 64 assert_se(strv_env_unset(l, "SCHLUMPF") == l);
940bd473 65
9b5d6bd9
LP
66 assert_se(streq(l[0], "PIEP"));
67 assert_se(streq(l[1], "NANANANA=YES"));
68 assert_se(strv_length(l) == 2);
940bd473
TA
69}
70
71static void test_strv_env_set(void) {
72 _cleanup_strv_free_ char **l = NULL, **r = NULL;
73
74 l = strv_new("PIEP", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
9b5d6bd9 75 assert_se(l);
940bd473
TA
76
77 r = strv_env_set(l, "WALDO=WALDO");
9b5d6bd9 78 assert_se(r);
940bd473 79
9b5d6bd9
LP
80 assert_se(streq(r[0], "PIEP"));
81 assert_se(streq(r[1], "SCHLUMPF=SMURFF"));
82 assert_se(streq(r[2], "NANANANA=YES"));
83 assert_se(streq(r[3], "WALDO=WALDO"));
84 assert_se(strv_length(r) == 4);
940bd473
TA
85}
86
1f28b2de
TA
87static void test_strv_env_merge(void) {
88 _cleanup_strv_free_ char **a = NULL, **b = NULL, **r = NULL;
89
90 a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL);
9b5d6bd9
LP
91 assert_se(a);
92
1f28b2de 93 b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
9b5d6bd9 94 assert_se(b);
c24eb49e 95
1f28b2de 96 r = strv_env_merge(2, a, b);
9b5d6bd9
LP
97 assert_se(r);
98 assert_se(streq(r[0], "FOO="));
99 assert_se(streq(r[1], "WALDO="));
100 assert_se(streq(r[2], "PIEP"));
101 assert_se(streq(r[3], "SCHLUMPF=SMURFF"));
102 assert_se(streq(r[4], "PIEP="));
103 assert_se(streq(r[5], "NANANANA=YES"));
104 assert_se(strv_length(r) == 6);
105
106 assert_se(strv_env_clean(r) == r);
107 assert_se(streq(r[0], "FOO="));
108 assert_se(streq(r[1], "WALDO="));
109 assert_se(streq(r[2], "SCHLUMPF=SMURFF"));
110 assert_se(streq(r[3], "PIEP="));
111 assert_se(streq(r[4], "NANANANA=YES"));
112 assert_se(strv_length(r) == 5);
1f28b2de
TA
113}
114
37f3ffca
RS
115static void test_env_strv_get_n(void) {
116 const char *_env[] = {
117 "FOO=NO NO NO",
118 "FOO=BAR BAR",
119 "BAR=waldo",
120 "PATH=unset",
121 NULL
122 };
123 char **env = (char**) _env;
124
125 assert_se(streq(strv_env_get_n(env, "FOO__", 3, 0), "BAR BAR"));
126 assert_se(streq(strv_env_get_n(env, "FOO__", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
127 assert_se(streq(strv_env_get_n(env, "FOO", 3, 0), "BAR BAR"));
128 assert_se(streq(strv_env_get_n(env, "FOO", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
129
130 assert_se(streq(strv_env_get_n(env, "PATH__", 4, 0), "unset"));
131 assert_se(streq(strv_env_get_n(env, "PATH", 4, 0), "unset"));
132 assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
133 assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
134
135 env[3] = NULL; /* kill our $PATH */
136
137 assert_se(!strv_env_get_n(env, "PATH__", 4, 0));
138 assert_se(!strv_env_get_n(env, "PATH", 4, 0));
139 assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT),
140 getenv("PATH")));
141 assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT),
142 getenv("PATH")));
143}
144
ccad1fd0
ZJS
145static void test_replace_env(bool braceless) {
146 const char *env[] = {
147 "FOO=BAR BAR",
148 "BAR=waldo",
149 NULL
150 };
151 _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL;
152 unsigned flags = REPLACE_ENV_ALLOW_BRACELESS*braceless;
153
154 t = replace_env("FOO=$FOO=${FOO}", (char**) env, flags);
155 assert_se(streq(t, braceless ? "FOO=BAR BAR=BAR BAR" : "FOO=$FOO=BAR BAR"));
156
157 s = replace_env("BAR=$BAR=${BAR}", (char**) env, flags);
158 assert_se(streq(s, braceless ? "BAR=waldo=waldo" : "BAR=$BAR=waldo"));
159
160 q = replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags);
161 assert_se(streq(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR="));
162
163 q = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
164 assert_se(streq(q, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
165
166 p = replace_env("${BAR}$BAR$BAR", (char**) env, flags);
167 assert_se(streq(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR"));
168}
169
170static void test_replace_env_argv(void) {
c24eb49e
LP
171 const char *env[] = {
172 "FOO=BAR BAR",
173 "BAR=waldo",
174 NULL
175 };
c24eb49e
LP
176 const char *line[] = {
177 "FOO$FOO",
178 "FOO$FOOFOO",
179 "FOO${FOO}$FOO",
180 "FOO${FOO}",
181 "${FOO}",
182 "$FOO",
183 "$FOO$FOO",
184 "${FOO}${BAR}",
185 "${FOO",
df553b58
MS
186 "FOO$$${FOO}",
187 "$$FOO${FOO}",
b82f58bf
RS
188 "${FOO:-${BAR}}",
189 "${QUUX:-${FOO}}",
190 "${FOO:+${BAR}}",
191 "${QUUX:+${BAR}}",
192 "${FOO:+|${BAR}|}}",
193 "${FOO:+|${BAR}{|}",
c24eb49e
LP
194 NULL
195 };
1f28b2de 196 _cleanup_strv_free_ char **r = NULL;
c24eb49e
LP
197
198 r = replace_env_argv((char**) line, (char**) env);
9b5d6bd9
LP
199 assert_se(r);
200 assert_se(streq(r[0], "FOO$FOO"));
201 assert_se(streq(r[1], "FOO$FOOFOO"));
202 assert_se(streq(r[2], "FOOBAR BAR$FOO"));
203 assert_se(streq(r[3], "FOOBAR BAR"));
204 assert_se(streq(r[4], "BAR BAR"));
205 assert_se(streq(r[5], "BAR"));
206 assert_se(streq(r[6], "BAR"));
207 assert_se(streq(r[7], "BAR BARwaldo"));
208 assert_se(streq(r[8], "${FOO"));
df553b58
MS
209 assert_se(streq(r[9], "FOO$BAR BAR"));
210 assert_se(streq(r[10], "$FOOBAR BAR"));
b82f58bf
RS
211 assert_se(streq(r[11], "${FOO:-waldo}"));
212 assert_se(streq(r[12], "${QUUX:-BAR BAR}"));
213 assert_se(streq(r[13], "${FOO:+waldo}"));
214 assert_se(streq(r[14], "${QUUX:+waldo}"));
215 assert_se(streq(r[15], "${FOO:+|waldo|}}"));
216 assert_se(streq(r[16], "${FOO:+|waldo{|}"));
217 assert_se(strv_length(r) == 17);
1f28b2de 218}
a6ff950e 219
4d1a6904 220static void test_env_clean(void) {
4d1a6904
LP
221 _cleanup_strv_free_ char **e;
222
223 e = strv_new("FOOBAR=WALDO",
224 "FOOBAR=WALDO",
225 "FOOBAR",
226 "F",
227 "X=",
228 "F=F",
229 "=",
230 "=F",
231 "",
232 "0000=000",
233 "äöüß=abcd",
234 "abcd=äöüß",
235 "xyz\n=xyz",
236 "xyz=xyz\n",
237 "another=one",
238 "another=final one",
239 NULL);
9b5d6bd9
LP
240 assert_se(e);
241 assert_se(!strv_env_is_valid(e));
242 assert_se(strv_env_clean(e) == e);
243 assert_se(strv_env_is_valid(e));
4d1a6904
LP
244
245 assert_se(streq(e[0], "FOOBAR=WALDO"));
246 assert_se(streq(e[1], "X="));
247 assert_se(streq(e[2], "F=F"));
248 assert_se(streq(e[3], "abcd=äöüß"));
249 assert_se(streq(e[4], "another=final one"));
250 assert_se(e[5] == NULL);
251}
252
8354c34e
TA
253static void test_env_name_is_valid(void) {
254 assert_se(env_name_is_valid("test"));
255
256 assert_se(!env_name_is_valid(NULL));
257 assert_se(!env_name_is_valid(""));
b8c83cfc
ZJS
258 assert_se(!env_name_is_valid("xxx\a"));
259 assert_se(!env_name_is_valid("xxx\007b"));
260 assert_se(!env_name_is_valid("\007\009"));
8354c34e
TA
261 assert_se(!env_name_is_valid("5_starting_with_a_number_is_wrong"));
262 assert_se(!env_name_is_valid("#¤%&?_only_numbers_letters_and_underscore_allowed"));
263}
264
b8c83cfc
ZJS
265static void test_env_value_is_valid(void) {
266 assert_se(env_value_is_valid(""));
267 assert_se(env_value_is_valid("głąb kapuściany"));
268 assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
269}
270
271static void test_env_assignment_is_valid(void) {
272 assert_se(env_assignment_is_valid("a="));
273 assert_se(env_assignment_is_valid("b=głąb kapuściany"));
274 assert_se(env_assignment_is_valid("c=\\007\\009\\011"));
275 assert_se(env_assignment_is_valid("e=printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
276
277 assert_se(!env_assignment_is_valid("="));
278 assert_se(!env_assignment_is_valid("a b="));
279 assert_se(!env_assignment_is_valid("a ="));
280 assert_se(!env_assignment_is_valid(" b="));
281 /* no dots or dashes: http://tldp.org/LDP/abs/html/gotchas.html */
282 assert_se(!env_assignment_is_valid("a.b="));
283 assert_se(!env_assignment_is_valid("a-b="));
284 assert_se(!env_assignment_is_valid("\007=głąb kapuściany"));
285 assert_se(!env_assignment_is_valid("c\009=\007\009\011"));
286 assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
287}
288
1f28b2de 289int main(int argc, char *argv[]) {
940bd473 290 test_strv_env_delete();
6162512c 291 test_strv_env_get();
940bd473
TA
292 test_strv_env_unset();
293 test_strv_env_set();
1f28b2de 294 test_strv_env_merge();
37f3ffca 295 test_env_strv_get_n();
ccad1fd0
ZJS
296 test_replace_env(false);
297 test_replace_env(true);
298 test_replace_env_argv();
4d1a6904 299 test_env_clean();
8354c34e 300 test_env_name_is_valid();
b8c83cfc
ZJS
301 test_env_value_is_valid();
302 test_env_assignment_is_valid();
a6ff950e 303
5f7c426e 304 return 0;
c24eb49e 305}