]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-env-file.c
env-util: make write_env_file() optionally take headers
[thirdparty/systemd.git] / src / test / test-env-file.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
cf95bc1d
ZJS
2
3#include "env-file.h"
4#include "fd-util.h"
55f99c26 5#include "fileio.h"
cf95bc1d
ZJS
6#include "fs-util.h"
7#include "macro.h"
8#include "strv.h"
9#include "tests.h"
10#include "tmpfile-util.h"
11
25407ad2
ZJS
12/* In case of repeating keys, later entries win. */
13
cf95bc1d 14#define env_file_1 \
25407ad2
ZJS
15 "a=a\n" \
16 "a=b\n" \
17 "a=b\n" \
cf95bc1d
ZJS
18 "a=a\n" \
19 "b=b\\\n" \
20 "c\n" \
e9e982a2
ZJS
21 "d= d\\\n" \
22 "e \\\n" \
23 "f \n" \
cf95bc1d 24 "g=g\\ \n" \
e503019b 25 "h= ąęół\\ śćńźżμ \n" \
cf95bc1d
ZJS
26 "i=i\\"
27
28#define env_file_2 \
29 "a=a\\\n"
30
31#define env_file_3 \
32 "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \
33 "#--nouser-config \\\n" \
cd93ec5e 34 "normal1=line\\\n" \
35 "111\n" \
e9e982a2 36 ";normal=ignored \\\n" \
cd93ec5e 37 "normal2=line222\n" \
e9e982a2
ZJS
38 "normal ignored \\\n"
39
40#define env_file_4 \
41 "# Generated\n" \
42 "\n" \
43 "HWMON_MODULES=\"coretemp f71882fg\"\n" \
44 "\n" \
45 "# For compatibility reasons\n" \
46 "\n" \
47 "MODULE_0=coretemp\n" \
48 "MODULE_1=f71882fg"
cf95bc1d
ZJS
49
50#define env_file_5 \
e9e982a2 51 "a=\n" \
cf95bc1d
ZJS
52 "b="
53
e9e982a2
ZJS
54#define env_file_6 \
55 "a=\\ \\n \\t \\x \\y \\' \n" \
56 "b= \\$' \n" \
57 "c= ' \\n\\t\\$\\`\\\\\n" \
58 "' \n" \
59 "d= \" \\n\\t\\$\\`\\\\\n" \
60 "\" \n"
61
4f7452a8 62TEST(load_env_file_1) {
cf95bc1d 63 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 64 assert_se(write_tmpfile(name, env_file_1) == 0);
cf95bc1d 65
367c47c8
ZJS
66 _cleanup_strv_free_ char **data = NULL;
67 assert_se(load_env_file(NULL, name, &data) == 0);
cf95bc1d
ZJS
68 assert_se(streq(data[0], "a=a"));
69 assert_se(streq(data[1], "b=bc"));
e9e982a2 70 assert_se(streq(data[2], "d=de f"));
cf95bc1d 71 assert_se(streq(data[3], "g=g "));
e503019b 72 assert_se(streq(data[4], "h=ąęół śćńźżμ"));
cf95bc1d
ZJS
73 assert_se(streq(data[5], "i=i"));
74 assert_se(data[6] == NULL);
75}
76
4f7452a8 77TEST(load_env_file_2) {
cf95bc1d 78 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 79 assert_se(write_tmpfile(name, env_file_2) == 0);
cf95bc1d 80
367c47c8
ZJS
81 _cleanup_strv_free_ char **data = NULL;
82 assert_se(load_env_file(NULL, name, &data) == 0);
cf95bc1d
ZJS
83 assert_se(streq(data[0], "a=a"));
84 assert_se(data[1] == NULL);
85}
86
4f7452a8 87TEST(load_env_file_3) {
cf95bc1d 88 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 89 assert_se(write_tmpfile(name, env_file_3) == 0);
cf95bc1d 90
367c47c8
ZJS
91 _cleanup_strv_free_ char **data = NULL;
92 assert_se(load_env_file(NULL, name, &data) == 0);
cd93ec5e 93 assert_se(streq(data[0], "normal1=line111"));
94 assert_se(streq(data[1], "normal2=line222"));
95 assert_se(data[2] == NULL);
cf95bc1d
ZJS
96}
97
4f7452a8 98TEST(load_env_file_4) {
cf95bc1d 99 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 100 assert_se(write_tmpfile(name, env_file_4) == 0);
cf95bc1d 101
367c47c8
ZJS
102 _cleanup_strv_free_ char **data = NULL;
103 assert_se(load_env_file(NULL, name, &data) == 0);
cf95bc1d
ZJS
104 assert_se(streq(data[0], "HWMON_MODULES=coretemp f71882fg"));
105 assert_se(streq(data[1], "MODULE_0=coretemp"));
106 assert_se(streq(data[2], "MODULE_1=f71882fg"));
107 assert_se(data[3] == NULL);
108}
109
4f7452a8 110TEST(load_env_file_5) {
cf95bc1d 111 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 112 assert_se(write_tmpfile(name, env_file_5) == 0);
cf95bc1d 113
367c47c8
ZJS
114 _cleanup_strv_free_ char **data = NULL;
115 assert_se(load_env_file(NULL, name, &data) == 0);
cf95bc1d
ZJS
116 assert_se(streq(data[0], "a="));
117 assert_se(streq(data[1], "b="));
118 assert_se(data[2] == NULL);
119}
120
e9e982a2 121TEST(load_env_file_6) {
e9e982a2 122 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
367c47c8 123 assert_se(write_tmpfile(name, env_file_6) == 0);
e9e982a2 124
367c47c8
ZJS
125 _cleanup_strv_free_ char **data = NULL;
126 assert_se(load_env_file(NULL, name, &data) == 0);
e9e982a2
ZJS
127 assert_se(streq(data[0], "a= n t x y '"));
128 assert_se(streq(data[1], "b=$'"));
129 assert_se(streq(data[2], "c= \\n\\t\\$\\`\\\\\n"));
130 assert_se(streq(data[3], "d= \\n\\t$`\\\n"));
131 assert_se(data[4] == NULL);
132}
133
841834d9
FS
134TEST(load_env_file_invalid_utf8) {
135 /* Test out a couple of assignments where the key/value has an invalid
136 * UTF-8 character ("noncharacter")
137 *
138 * See: https://en.wikipedia.org/wiki/Universal_Character_Set_characters#Non-characters
139 */
140 FOREACH_STRING(s,
141 "fo\ufffeo=bar",
142 "foo=b\uffffar",
143 "baz=hello world\ufffe") {
144 _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX";
145 assert_se(write_tmpfile(name, s) == 0);
146
147 _cleanup_strv_free_ char **data = NULL;
148 assert_se(load_env_file(NULL, name, &data) == -EINVAL);
149 assert_se(!data);
150 }
151}
152
4f7452a8 153TEST(write_and_load_env_file) {
55f99c26
LP
154 /* Make sure that our writer, parser and the shell agree on what our env var files mean */
155
156 FOREACH_STRING(v,
157 "obbardc-laptop",
158 "obbardc\\-laptop",
159 "obbardc-lap\\top",
160 "obbardc-lap\\top",
161 "obbardc-lap\\\\top",
162 "double\"quote",
163 "single\'quote",
164 "dollar$dollar",
165 "newline\nnewline") {
166 _cleanup_(unlink_and_freep) char *p = NULL;
167 _cleanup_strv_free_ char **l = NULL;
168 _cleanup_free_ char *j = NULL, *w = NULL, *cmd = NULL, *from_shell = NULL;
649bde89 169 _cleanup_pclose_ FILE *f = NULL;
55f99c26
LP
170 size_t sz;
171
172 assert_se(tempfn_random_child(NULL, NULL, &p) >= 0);
173
174 assert_se(j = strjoin("TEST=", v));
f155cb6d 175 assert_se(write_env_file(AT_FDCWD, p, STRV_MAKE("# header 1", "", "# header 2"), STRV_MAKE(j)) >= 0);
55f99c26
LP
176
177 assert_se(cmd = strjoin(". ", p, " && /bin/echo -n \"$TEST\""));
178 assert_se(f = popen(cmd, "re"));
179 assert_se(read_full_stream(f, &from_shell, &sz) >= 0);
180 assert_se(sz == strlen(v));
181 assert_se(streq(from_shell, v));
182
183 assert_se(load_env_file(NULL, p, &l) >= 0);
184 assert_se(strv_equal(l, STRV_MAKE(j)));
185
186 assert_se(parse_env_file(NULL, p, "TEST", &w) >= 0);
187 assert_se(streq_ptr(w, v));
188 }
189}
190
4f7452a8 191DEFINE_TEST_MAIN(LOG_INFO);