Add a self-test for cli-utils.c
[external/binutils.git] / gdb / unittests / environ-selftests.c
1 /* Self tests for gdb_environ for GDB, the GNU debugger.
2
3    Copyright (C) 2017-2018 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "selftest.h"
22 #include "common/environ.h"
23 #include "diagnostics.h"
24
25 static const char gdb_selftest_env_var[] = "GDB_SELFTEST_ENVIRON";
26
27 static bool
28 set_contains (const std::set<std::string> &set, std::string key)
29 {
30   return set.find (key) != set.end ();
31 }
32
33 namespace selftests {
34 namespace gdb_environ_tests {
35
36 /* Test if the vector is initialized in a correct way.  */
37
38 static void
39 test_vector_initialization ()
40 {
41   gdb_environ env;
42
43   /* When the vector is initialized, there should always be one NULL
44      element in it.  */
45   SELF_CHECK (env.envp ()[0] == NULL);
46   SELF_CHECK (env.user_set_env ().size () == 0);
47   SELF_CHECK (env.user_unset_env ().size () == 0);
48
49   /* Make sure that there is no other element.  */
50   SELF_CHECK (env.get ("PWD") == NULL);
51 }
52
53 /* Test initialization using the host's environ.  */
54
55 static void
56 test_init_from_host_environ ()
57 {
58   /* Initialize the environment vector using the host's environ.  */
59   gdb_environ env = gdb_environ::from_host_environ ();
60
61   /* The user-set and user-unset lists must be empty.  */
62   SELF_CHECK (env.user_set_env ().size () == 0);
63   SELF_CHECK (env.user_unset_env ().size () == 0);
64
65   /* Our test environment variable should be present at the
66      vector.  */
67   SELF_CHECK (strcmp (env.get (gdb_selftest_env_var), "1") == 0);
68 }
69
70 /* Test reinitialization using the host's environ.  */
71
72 static void
73 test_reinit_from_host_environ ()
74 {
75   /* Reinitialize our environ vector using the host environ.  We
76      should be able to see one (and only one) instance of the test
77      variable.  */
78   gdb_environ env = gdb_environ::from_host_environ ();
79   env = gdb_environ::from_host_environ ();
80   char **envp = env.envp ();
81   int num_found = 0;
82
83   for (size_t i = 0; envp[i] != NULL; ++i)
84     if (strcmp (envp[i], "GDB_SELFTEST_ENVIRON=1") == 0)
85       ++num_found;
86   SELF_CHECK (num_found == 1);
87 }
88
89 /* Test the case when we set a variable A, then set a variable B,
90    then unset A, and make sure that we cannot find A in the environ
91    vector, but can still find B.  */
92
93 static void
94 test_set_A_unset_B_unset_A_cannot_find_A_can_find_B ()
95 {
96   gdb_environ env;
97
98   env.set ("GDB_SELFTEST_ENVIRON_1", "aaa");
99   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_1"), "aaa") == 0);
100   /* User-set environ var list must contain one element.  */
101   SELF_CHECK (env.user_set_env ().size () == 1);
102   SELF_CHECK (set_contains (env.user_set_env (),
103                             std::string ("GDB_SELFTEST_ENVIRON_1=aaa")));
104
105   env.set ("GDB_SELFTEST_ENVIRON_2", "bbb");
106   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);
107
108   env.unset ("GDB_SELFTEST_ENVIRON_1");
109   SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON_1") == NULL);
110   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0);
111
112   /* The user-set environ var list must contain only one element
113      now.  */
114   SELF_CHECK (set_contains (env.user_set_env (),
115                             std::string ("GDB_SELFTEST_ENVIRON_2=bbb")));
116   SELF_CHECK (env.user_set_env ().size () == 1);
117 }
118
119 /* Check if unset followed by a set in an empty vector works.  */
120
121 static void
122 test_unset_set_empty_vector ()
123 {
124   gdb_environ env;
125
126   env.set ("PWD", "test");
127   SELF_CHECK (strcmp (env.get ("PWD"), "test") == 0);
128   SELF_CHECK (set_contains (env.user_set_env (), std::string ("PWD=test")));
129   SELF_CHECK (env.user_unset_env ().size () == 0);
130   /* The second element must be NULL.  */
131   SELF_CHECK (env.envp ()[1] == NULL);
132   SELF_CHECK (env.user_set_env ().size () == 1);
133   env.unset ("PWD");
134   SELF_CHECK (env.envp ()[0] == NULL);
135   SELF_CHECK (env.user_set_env ().size () == 0);
136   SELF_CHECK (env.user_unset_env ().size () == 1);
137   SELF_CHECK (set_contains (env.user_unset_env (), std::string ("PWD")));
138 }
139
140 /* When we clear our environ vector, there should be only one
141    element on it (NULL), and we shouldn't be able to get our test
142    variable.  */
143
144 static void
145 test_vector_clear ()
146 {
147   gdb_environ env;
148
149   env.set (gdb_selftest_env_var, "1");
150
151   env.clear ();
152   SELF_CHECK (env.envp ()[0] == NULL);
153   SELF_CHECK (env.user_set_env ().size () == 0);
154   SELF_CHECK (env.user_unset_env ().size () == 0);
155   SELF_CHECK (env.get (gdb_selftest_env_var) == NULL);
156 }
157
158 /* Test that after a std::move the moved-from object is left at a
159    valid state (i.e., its only element is NULL).  */
160
161 static void
162 test_std_move ()
163 {
164   gdb_environ env;
165   gdb_environ env2;
166
167   env.set ("A", "1");
168   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
169   SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
170   SELF_CHECK (env.user_set_env ().size () == 1);
171
172   env2 = std::move (env);
173   SELF_CHECK (env.envp ()[0] == NULL);
174   SELF_CHECK (strcmp (env2.get ("A"), "1") == 0);
175   SELF_CHECK (env2.envp ()[1] == NULL);
176   SELF_CHECK (env.user_set_env ().size () == 0);
177   SELF_CHECK (set_contains (env2.user_set_env (), std::string ("A=1")));
178   SELF_CHECK (env2.user_set_env ().size () == 1);
179   env.set ("B", "2");
180   SELF_CHECK (strcmp (env.get ("B"), "2") == 0);
181   SELF_CHECK (env.envp ()[1] == NULL);
182 }
183
184 /* Test that the move constructor leaves everything at a valid
185    state.  */
186
187 static void
188 test_move_constructor ()
189 {
190   gdb_environ env;
191
192   env.set ("A", "1");
193   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
194   SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
195
196   gdb_environ env2 = std::move (env);
197   SELF_CHECK (env.envp ()[0] == NULL);
198   SELF_CHECK (env.user_set_env ().size () == 0);
199   SELF_CHECK (strcmp (env2.get ("A"), "1") == 0);
200   SELF_CHECK (env2.envp ()[1] == NULL);
201   SELF_CHECK (set_contains (env2.user_set_env (), std::string ("A=1")));
202   SELF_CHECK (env2.user_set_env ().size () == 1);
203
204   env.set ("B", "2");
205   SELF_CHECK (strcmp (env.get ("B"), "2") == 0);
206   SELF_CHECK (env.envp ()[1] == NULL);
207   SELF_CHECK (set_contains (env.user_set_env (), std::string ("B=2")));
208   SELF_CHECK (env.user_set_env ().size () == 1);
209 }
210
211 /* Test that self-moving works.  */
212
213 static void
214 test_self_move ()
215 {
216   gdb_environ env;
217
218   /* Test self-move.  */
219   env.set ("A", "1");
220   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
221   SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
222   SELF_CHECK (env.user_set_env ().size () == 1);
223
224   /* Some compilers warn about moving to self, but that's precisely what we want
225      to test here, so turn this warning off.  */
226   DIAGNOSTIC_PUSH
227   DIAGNOSTIC_IGNORE_SELF_MOVE
228   env = std::move (env);
229   DIAGNOSTIC_POP
230
231   SELF_CHECK (strcmp (env.get ("A"), "1") == 0);
232   SELF_CHECK (strcmp (env.envp ()[0], "A=1") == 0);
233   SELF_CHECK (env.envp ()[1] == NULL);
234   SELF_CHECK (set_contains (env.user_set_env (), std::string ("A=1")));
235   SELF_CHECK (env.user_set_env ().size () == 1);
236 }
237
238 /* Test if set/unset/reset works.  */
239
240 static void
241 test_set_unset_reset ()
242 {
243   gdb_environ env = gdb_environ::from_host_environ ();
244
245   /* Our test variable should already be present in the host's environment.  */
246   SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") != NULL);
247
248   /* Set our test variable to another value.  */
249   env.set ("GDB_SELFTEST_ENVIRON", "test");
250   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "test") == 0);
251   SELF_CHECK (env.user_set_env ().size () == 1);
252   SELF_CHECK (env.user_unset_env ().size () == 0);
253
254   /* And unset our test variable.  The variable still exists in the
255      host's environment, but doesn't exist in our vector.  */
256   env.unset ("GDB_SELFTEST_ENVIRON");
257   SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL);
258   SELF_CHECK (env.user_set_env ().size () == 0);
259   SELF_CHECK (env.user_unset_env ().size () == 1);
260   SELF_CHECK (set_contains (env.user_unset_env (),
261                             std::string ("GDB_SELFTEST_ENVIRON")));
262
263   /* Re-set the test variable.  */
264   env.set ("GDB_SELFTEST_ENVIRON", "1");
265   SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0);
266 }
267
268 static void
269 run_tests ()
270 {
271   /* Set a test environment variable.  */
272   if (setenv ("GDB_SELFTEST_ENVIRON", "1", 1) != 0)
273     error (_("Could not set environment variable for testing."));
274
275   test_vector_initialization ();
276
277   test_unset_set_empty_vector ();
278
279   test_init_from_host_environ ();
280
281   test_set_unset_reset ();
282
283   test_vector_clear ();
284
285   test_reinit_from_host_environ ();
286
287   /* Get rid of our test variable.  We won't need it anymore.  */
288   unsetenv ("GDB_SELFTEST_ENVIRON");
289
290   test_set_A_unset_B_unset_A_cannot_find_A_can_find_B ();
291
292   test_std_move ();
293
294   test_move_constructor ();
295
296   test_self_move ();
297 }
298 } /* namespace gdb_environ */
299 } /* namespace selftests */
300
301 void
302 _initialize_environ_selftests ()
303 {
304   selftests::register_test ("gdb_environ",
305                             selftests::gdb_environ_tests::run_tests);
306 }