Commit | Line | Data |
---|---|---|
9a6c7d9c SDJ |
1 | /* Self tests for gdb_environ for GDB, the GNU debugger. |
2 | ||
3 | Copyright (C) 2017 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" | |
f4906a9a | 23 | #include "common/diagnostics.h" |
9a6c7d9c SDJ |
24 | |
25 | namespace selftests { | |
26 | namespace gdb_environ_tests { | |
27 | ||
28 | static void | |
29 | run_tests () | |
30 | { | |
31 | /* Set a test environment variable. This will be unset at the end | |
32 | of this function. */ | |
33 | if (setenv ("GDB_SELFTEST_ENVIRON", "1", 1) != 0) | |
34 | error (_("Could not set environment variable for testing.")); | |
35 | ||
36 | gdb_environ env; | |
37 | ||
38 | /* When the vector is initialized, there should always be one NULL | |
39 | element in it. */ | |
40 | SELF_CHECK (env.envp ()[0] == NULL); | |
41 | ||
42 | /* Make sure that there is no other element. */ | |
43 | SELF_CHECK (env.get ("PWD") == NULL); | |
44 | ||
45 | /* Check if unset followed by a set in an empty vector works. */ | |
46 | env.set ("PWD", "test"); | |
47 | SELF_CHECK (strcmp (env.get ("PWD"), "test") == 0); | |
48 | /* The second element must be NULL. */ | |
49 | SELF_CHECK (env.envp ()[1] == NULL); | |
50 | env.unset ("PWD"); | |
51 | SELF_CHECK (env.envp ()[0] == NULL); | |
52 | ||
53 | /* Initialize the environment vector using the host's environ. */ | |
54 | env = gdb_environ::from_host_environ (); | |
55 | ||
56 | /* Our test environment variable should be present at the | |
57 | vector. */ | |
58 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0); | |
59 | ||
60 | /* Set our test variable to another value. */ | |
61 | env.set ("GDB_SELFTEST_ENVIRON", "test"); | |
62 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "test") == 0); | |
63 | ||
64 | /* And unset our test variable. The variable still exists in the | |
65 | host's environment, but doesn't exist in our vector. */ | |
66 | env.unset ("GDB_SELFTEST_ENVIRON"); | |
67 | SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL); | |
68 | ||
69 | /* Re-set the test variable. */ | |
70 | env.set ("GDB_SELFTEST_ENVIRON", "1"); | |
71 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON"), "1") == 0); | |
72 | ||
73 | /* When we clear our environ vector, there should be only one | |
74 | element on it (NULL), and we shouldn't be able to get our test | |
75 | variable. */ | |
76 | env.clear (); | |
77 | SELF_CHECK (env.envp ()[0] == NULL); | |
78 | SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON") == NULL); | |
79 | ||
80 | /* Reinitialize our environ vector using the host environ. We | |
81 | should be able to see one (and only one) instance of the test | |
82 | variable. */ | |
83 | env = gdb_environ::from_host_environ (); | |
84 | char **envp = env.envp (); | |
85 | int num_found = 0; | |
86 | ||
87 | for (size_t i = 0; envp[i] != NULL; ++i) | |
88 | if (strcmp (envp[i], "GDB_SELFTEST_ENVIRON=1") == 0) | |
89 | ++num_found; | |
90 | SELF_CHECK (num_found == 1); | |
91 | ||
92 | /* Get rid of our test variable. */ | |
93 | unsetenv ("GDB_SELFTEST_ENVIRON"); | |
94 | ||
95 | /* Test the case when we set a variable A, then set a variable B, | |
96 | then unset A, and make sure that we cannot find A in the environ | |
97 | vector, but can still find B. */ | |
98 | env.set ("GDB_SELFTEST_ENVIRON_1", "aaa"); | |
99 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_1"), "aaa") == 0); | |
100 | ||
101 | env.set ("GDB_SELFTEST_ENVIRON_2", "bbb"); | |
102 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0); | |
103 | ||
104 | env.unset ("GDB_SELFTEST_ENVIRON_1"); | |
105 | SELF_CHECK (env.get ("GDB_SELFTEST_ENVIRON_1") == NULL); | |
106 | SELF_CHECK (strcmp (env.get ("GDB_SELFTEST_ENVIRON_2"), "bbb") == 0); | |
107 | ||
108 | env.clear (); | |
109 | ||
110 | /* Test that after a std::move the moved-from object is left at a | |
111 | valid state (i.e., its only element is NULL). */ | |
112 | env.set ("A", "1"); | |
113 | SELF_CHECK (strcmp (env.get ("A"), "1") == 0); | |
114 | gdb_environ env2; | |
115 | env2 = std::move (env); | |
116 | SELF_CHECK (env.envp ()[0] == NULL); | |
117 | SELF_CHECK (strcmp (env2.get ("A"), "1") == 0); | |
118 | SELF_CHECK (env2.envp ()[1] == NULL); | |
119 | env.set ("B", "2"); | |
120 | SELF_CHECK (strcmp (env.get ("B"), "2") == 0); | |
121 | SELF_CHECK (env.envp ()[1] == NULL); | |
122 | ||
123 | /* Test that the move constructor leaves everything at a valid | |
124 | state. */ | |
125 | env.clear (); | |
126 | env.set ("A", "1"); | |
127 | SELF_CHECK (strcmp (env.get ("A"), "1") == 0); | |
128 | gdb_environ env3 = std::move (env); | |
129 | SELF_CHECK (env.envp ()[0] == NULL); | |
130 | SELF_CHECK (strcmp (env3.get ("A"), "1") == 0); | |
131 | SELF_CHECK (env3.envp ()[1] == NULL); | |
132 | env.set ("B", "2"); | |
133 | SELF_CHECK (strcmp (env.get ("B"), "2") == 0); | |
134 | SELF_CHECK (env.envp ()[1] == NULL); | |
135 | ||
136 | /* Test self-move. */ | |
137 | env.clear (); | |
138 | env.set ("A", "1"); | |
139 | SELF_CHECK (strcmp (env.get ("A"), "1") == 0); | |
f4906a9a PA |
140 | |
141 | /* Some compilers warn about moving to self, but that's precisely what we want | |
142 | to test here, so turn this warning off. */ | |
143 | DIAGNOSTIC_PUSH | |
144 | DIAGNOSTIC_IGNORE_SELF_MOVE | |
9a6c7d9c | 145 | env = std::move (env); |
f4906a9a PA |
146 | DIAGNOSTIC_POP |
147 | ||
9a6c7d9c SDJ |
148 | SELF_CHECK (strcmp (env.get ("A"), "1") == 0); |
149 | SELF_CHECK (strcmp (env.envp ()[0], "A=1") == 0); | |
150 | SELF_CHECK (env.envp ()[1] == NULL); | |
151 | } | |
152 | } /* namespace gdb_environ */ | |
153 | } /* namespace selftests */ | |
154 | ||
155 | void | |
156 | _initialize_environ_selftests () | |
157 | { | |
7649770c | 158 | selftests::register_test (selftests::gdb_environ_tests::run_tests); |
9a6c7d9c | 159 | } |