]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | #!/usr/bin/python |
2 | ||
3 | # Copyright 2014-2015 Steven Watanabe | |
4 | # Distributed under the Boost Software License, Version 1.0. | |
5 | # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
6 | ||
7 | # Tests the link-directory rule used to create the | |
8 | # common boost/ directory in the new git layout. | |
9 | ||
10 | import BoostBuild | |
11 | ||
12 | def ignore_config(t): | |
13 | """These files are created by the configuration logic in link.jam | |
14 | They may or may not exist, depending on the system.""" | |
15 | t.ignore("bin/symlink/test-hardlink") | |
16 | t.ignore("bin/test-hardlink-source") | |
17 | t.ignore("bin/test-symlink") | |
18 | t.ignore("bin/test-symlink-source") | |
19 | ||
20 | def test_basic(): | |
21 | """Test creation of a single link""" | |
22 | t = BoostBuild.Tester() | |
23 | t.write("jamroot.jam", """\ | |
24 | import link ; | |
25 | link-directory dir1-link : src/dir1/include : <location>. ; | |
26 | """) | |
27 | ||
28 | t.write("src/dir1/include/file1.h", "file1") | |
29 | ||
30 | t.run_build_system() | |
31 | ||
32 | t.expect_addition("include/file1.h") | |
33 | t.expect_content("include/file1.h", "file1") | |
34 | ignore_config(t) | |
35 | t.expect_nothing_more() | |
36 | t.cleanup() | |
37 | ||
38 | def test_merge_two(): | |
39 | """Test merging two directories""" | |
40 | t = BoostBuild.Tester() | |
41 | t.write("jamroot.jam", """\ | |
42 | import link ; | |
43 | link-directory dir1-link : src/dir1/include : <location>. ; | |
44 | link-directory dir2-link : src/dir2/include : <location>. ; | |
45 | """) | |
46 | ||
47 | t.write("src/dir1/include/file1.h", "file1") | |
48 | t.write("src/dir2/include/file2.h", "file2") | |
49 | ||
50 | t.run_build_system() | |
51 | ||
52 | t.expect_addition("include/file1.h") | |
53 | t.expect_content("include/file1.h", "file1") | |
54 | t.expect_addition("include/file2.h") | |
55 | t.expect_content("include/file2.h", "file2") | |
56 | ignore_config(t) | |
57 | t.expect_nothing_more() | |
58 | t.cleanup() | |
59 | ||
60 | def test_merge_existing(group1, group2): | |
61 | """Test adding a link when a different symlink already exists""" | |
62 | t = BoostBuild.Tester() | |
63 | t.write("jamroot.jam", """\ | |
64 | import link ; | |
65 | link-directory dir1-link : src/dir1/include : <location>. ; | |
66 | link-directory dir2-link : src/dir2/include : <location>. ; | |
67 | """) | |
68 | ||
69 | t.write("src/dir1/include/file1.h", "file1") | |
70 | t.write("src/dir2/include/file2.h", "file2") | |
71 | ||
72 | t.run_build_system(group1) | |
73 | ||
74 | if "dir1-link" in group1: | |
75 | t.expect_addition("include/file1.h") | |
76 | t.expect_content("include/file1.h", "file1") | |
77 | if "dir2-link" in group1: | |
78 | t.expect_addition("include/file2.h") | |
79 | t.expect_content("include/file2.h", "file2") | |
80 | ignore_config(t) | |
81 | t.expect_nothing_more() | |
82 | ||
83 | t.run_build_system(group2) | |
84 | ||
85 | if "dir1-link" in group2: | |
86 | if "dir1-link" not in group1: | |
87 | t.expect_addition("include/file1.h") | |
88 | t.expect_content("include/file1.h", "file1") | |
89 | else: | |
90 | t.ignore_removal("include/file1.h") | |
91 | ||
92 | if "dir2-link" in group2: | |
93 | if "dir2-link" not in group1: | |
94 | t.expect_addition("include/file2.h") | |
95 | t.expect_content("include/file2.h", "file2") | |
96 | else: | |
97 | t.ignore_removal("include/file2.h") | |
98 | ignore_config(t) | |
99 | t.expect_nothing_more() | |
100 | ||
101 | t.cleanup() | |
102 | ||
103 | def test_merge_existing_all(): | |
104 | test_merge_existing(["dir1-link"], ["dir2-link"]) | |
105 | test_merge_existing(["dir2-link"], ["dir1-link"]) | |
106 | test_merge_existing(["dir1-link"], ["dir1-link", "dir2-link"]) | |
107 | test_merge_existing(["dir2-link"], ["dir1-link", "dir2-link"]) | |
108 | ||
109 | def test_merge_recursive(): | |
110 | "Test merging several directories including common prefixes" | |
111 | t = BoostBuild.Tester() | |
112 | t.write("jamroot.jam", """\ | |
113 | import link ; | |
114 | link-directory dir1-link : src/dir1/include : <location>. ; | |
115 | link-directory dir2-link : src/dir2/include : <location>. ; | |
116 | link-directory dir3-link : src/dir3/include : <location>. ; | |
117 | """) | |
118 | ||
119 | t.write("src/dir1/include/file1.h", "file1") | |
120 | t.write("src/dir2/include/file2.h", "file2") | |
121 | t.write("src/dir2/include/nested/file3.h", "file3") | |
122 | t.write("src/dir3/include/nested/file4.h", "file4") | |
123 | ||
124 | t.run_build_system() | |
125 | ||
126 | t.expect_addition("include/file1.h") | |
127 | t.expect_content("include/file1.h", "file1") | |
128 | t.expect_addition("include/file2.h") | |
129 | t.expect_content("include/file2.h", "file2") | |
130 | t.expect_addition("include/nested/file3.h") | |
131 | t.expect_content("include/nested/file3.h", "file3") | |
132 | t.expect_addition("include/nested/file4.h") | |
133 | t.expect_content("include/nested/file4.h", "file4") | |
134 | ignore_config(t) | |
135 | t.expect_nothing_more() | |
136 | ||
137 | t.cleanup() | |
138 | ||
139 | def test_merge_recursive_existing(group1, group2): | |
140 | "Test merging several directories including common prefixes." | |
141 | t = BoostBuild.Tester() | |
142 | t.write("jamroot.jam", """\ | |
143 | import link ; | |
144 | link-directory dir1-link : src/dir1/include : <location>. ; | |
145 | link-directory dir2-link : src/dir2/include : <location>. ; | |
146 | link-directory dir3-link : src/dir3/include : <location>. ; | |
147 | link-directory dir4-link : src/dir4/include : <location>. ; | |
148 | link-directory dir5-link : src/dir5/include : <location>. ; | |
149 | """) | |
150 | ||
151 | t.write("src/dir1/include/file1.h", "file1") | |
152 | t.write("src/dir2/include/nested/file2.h", "file2") | |
153 | t.write("src/dir3/include/nested/file3.h", "file3") | |
154 | t.write("src/dir4/include/nested/xxx/yyy/file4.h", "file4") | |
155 | t.write("src/dir5/include/nested/xxx/yyy/file5.h", "file5") | |
156 | ||
157 | t.run_build_system(group1) | |
158 | t.run_build_system(group2 + ["-d+12"]) | |
159 | ||
160 | t.ignore_addition("include/file1.h") | |
161 | t.ignore_addition("include/nested/file2.h") | |
162 | t.ignore_addition("include/nested/file3.h") | |
163 | t.ignore_addition("include/nested/xxx/yyy/file4.h") | |
164 | t.ignore_addition("include/nested/xxx/yyy/file5.h") | |
165 | ignore_config(t) | |
166 | t.expect_nothing_more() | |
167 | ||
168 | t.cleanup() | |
169 | ||
170 | def test_merge_recursive_existing_all(): | |
171 | # These should create a link | |
172 | test_merge_recursive_existing(["dir2-link"], ["dir2-link", "dir1-link"]) | |
173 | test_merge_recursive_existing(["dir2-link"], ["dir1-link", "dir2-link"]) | |
174 | # These should create a directory | |
175 | test_merge_recursive_existing(["dir2-link"], ["dir2-link", "dir3-link"]) | |
176 | test_merge_recursive_existing(["dir2-link"], ["dir3-link", "dir2-link"]) | |
177 | # It should work even if we have to create many intermediate subdirectories | |
178 | test_merge_recursive_existing(["dir4-link"], ["dir4-link", "dir5-link"]) | |
179 | test_merge_recursive_existing(["dir4-link"], ["dir5-link", "dir4-link"]) | |
180 | ||
181 | def test_include_scan(): | |
182 | """Make sure that the #include scanner finds the headers""" | |
183 | t = BoostBuild.Tester() | |
184 | t.write("jamroot.jam", """\ | |
185 | import link ; | |
186 | link-directory dir1-link : src/dir1/include : <location>. ; | |
187 | link-directory dir2-link : src/dir2/include : <location>. ; | |
188 | obj test : test.cpp : | |
189 | <include>include | |
190 | <implicit-dependency>dir1-link | |
191 | <implicit-dependency>dir2-link ; | |
192 | """) | |
193 | ||
194 | t.write("src/dir1/include/file1.h", "#include <file2.h>\n") | |
195 | t.write("src/dir2/include/file2.h", "int f();\n") | |
196 | t.write("test.cpp", """\ | |
197 | #include <file1.h> | |
198 | int main() { f(); } | |
199 | """); | |
200 | ||
201 | t.run_build_system(["test"]) | |
202 | ||
203 | t.expect_addition("bin/$toolset/debug/test.obj") | |
204 | ||
205 | t.run_build_system() | |
206 | t.expect_nothing_more() | |
207 | ||
208 | t.cleanup() | |
209 | ||
210 | def test_include_scan_merge_existing(): | |
211 | """Make sure that files are replaced if needed when merging in | |
212 | a new directory""" | |
213 | t = BoostBuild.Tester() | |
214 | ||
215 | t.write("jamroot.jam", """\ | |
216 | import link ; | |
217 | link-directory dir1-link : src/dir1/include : <location>. ; | |
218 | link-directory dir2-link : src/dir2/include : <location>. ; | |
219 | obj test : test.cpp : | |
220 | <include>include | |
221 | <implicit-dependency>dir1-link | |
222 | <implicit-dependency>dir2-link ; | |
223 | """) | |
224 | ||
225 | t.write("src/dir1/include/file1.h", "int f();") | |
226 | t.write("src/dir2/include/file2.h", "#include <file1.h>") | |
227 | t.write("test.cpp", """\ | |
228 | #include <file2.h> | |
229 | int main() { f(); } | |
230 | """) | |
231 | ||
232 | t.run_build_system(["dir2-link"]) | |
233 | ||
234 | t.run_build_system(["test"]) | |
235 | t.expect_addition("include/file1.h") | |
236 | t.expect_addition("bin/$toolset/debug/test.obj") | |
237 | t.expect_nothing_more() | |
238 | ||
239 | t.cleanup() | |
240 | ||
241 | def test_update_file_link(params1, params2): | |
242 | """Tests the behavior of updates when changing the link mode. | |
243 | The link needs to be updated iff the original was a copy.""" | |
244 | t = BoostBuild.Tester() | |
245 | ||
246 | t.write("jamroot.jam", """\ | |
247 | import link ; | |
248 | import project ; | |
249 | import property-set ; | |
250 | import modules ; | |
251 | ||
252 | if --no-symlinks in [ modules.peek : ARGV ] | |
253 | { | |
254 | modules.poke link : .can-symlink : false ; | |
255 | } | |
256 | ||
257 | if --no-hardlinks in [ modules.peek : ARGV ] | |
258 | { | |
259 | modules.poke link : .can-hardlink : false ; | |
260 | } | |
261 | ||
262 | .project = [ project.current ] ; | |
263 | .has-files = [ glob include/file1.h ] ; | |
264 | ||
265 | rule can-link ( properties * ) { | |
266 | if ( ! [ link.can-symlink $(.project) : [ property-set.empty ] ] ) && | |
267 | ( ! [ link.can-hardlink $(.project) : [ property-set.empty ] ] ) | |
268 | { | |
269 | ECHO links unsupported ; | |
270 | } | |
271 | } | |
272 | ||
273 | # Use two directories so that we link to individual files. | |
274 | link-directory dir1-link : src/dir1/include : <location>. ; | |
275 | link-directory dir2-link : src/dir2/include : <location>. ; | |
276 | alias check-linking : : <conditional>@can-link ; | |
277 | """) | |
278 | t.write("src/dir1/include/file1.h", "file1") | |
279 | t.write("src/dir2/include/file2.h", "file2") | |
280 | ||
281 | t.run_build_system(params1) | |
282 | ignore_config(t) | |
283 | t.expect_addition("include/file1.h") | |
284 | t.expect_addition("include/file2.h") | |
285 | t.expect_nothing_more() | |
286 | ||
287 | using_links = "links unsupported" not in t.stdout() | |
288 | ||
289 | t.touch("src/dir1/include/file1.h") | |
290 | ||
291 | t.run_build_system(params2) | |
292 | if not using_links: t.expect_touch("include/file1.h") | |
293 | ignore_config(t) | |
294 | t.expect_nothing_more() | |
295 | ||
296 | t.cleanup() | |
297 | ||
298 | def test_update_file_link_all(): | |
299 | """Test all nine possible combinations of two runs.""" | |
300 | possible_args = [[], ["--no-symlinks"], ["--no-symlinks", "--no-hardlinks"]] | |
301 | for arg1 in possible_args: | |
302 | for arg2 in possible_args: | |
303 | test_update_file_link(arg1, arg2) | |
304 | ||
305 | def test_error_duplicate(): | |
306 | """Test that linking a single file from | |
307 | multiple sources causes a hard error.""" | |
308 | t = BoostBuild.Tester() | |
309 | ||
310 | t.write("jamroot.jam", """\ | |
311 | import link ; | |
312 | link-directory dir1-link : src/dir1/include : <location>. ; | |
313 | link-directory dir2-link : src/dir2/include : <location>. ; | |
314 | """) | |
315 | ||
316 | t.write("src/dir1/include/file1.h", "file1") | |
317 | t.write("src/dir2/include/file1.h", "file2") | |
318 | ||
319 | t.run_build_system(status=1) | |
320 | t.expect_output_lines( | |
321 | ["error: Cannot create link include/file1.h to src/dir2/include/file1.h.", | |
322 | "error: Link previously defined to another file, src/dir1/include/file1.h."]) | |
323 | ||
324 | t.cleanup() | |
325 | ||
326 | test_basic() | |
327 | test_merge_two() | |
328 | test_merge_existing_all() | |
329 | test_merge_recursive() | |
330 | test_merge_recursive_existing_all() | |
331 | test_include_scan() | |
332 | test_include_scan_merge_existing() | |
333 | test_update_file_link_all() | |
334 | test_error_duplicate() |