| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350 |
- #!/usr/bin/python
- # Copyright 2014-2015 Steven Watanabe
- # Distributed under the Boost Software License, Version 1.0.
- # (See accompanying file LICENSE.txt or https://www.bfgroup.xyz/b2/LICENSE.txt)
- # Tests the link-directory rule used to create the
- # common boost/ directory in the new git layout.
- import BoostBuild
- def ignore_config(t):
- """These files are created by the configuration logic in link.jam
- They may or may not exist, depending on the system."""
- t.ignore("bin/symlink/test-hardlink")
- t.ignore("bin/test-hardlink-source")
- t.ignore("bin/test-symlink")
- t.ignore("bin/test-symlink-source")
- def test_basic():
- """Test creation of a single link"""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.run_build_system()
- t.expect_addition("include/file1.h")
- t.expect_content("include/file1.h", "file1")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_merge_two():
- """Test merging two directories"""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/file2.h", "file2")
- t.run_build_system()
- t.expect_addition("include/file1.h")
- t.expect_content("include/file1.h", "file1")
- t.expect_addition("include/file2.h")
- t.expect_content("include/file2.h", "file2")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_merge_existing(group1, group2):
- """Test adding a link when a different symlink already exists"""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/file2.h", "file2")
- t.run_build_system(group1)
- if "dir1-link" in group1:
- t.expect_addition("include/file1.h")
- t.expect_content("include/file1.h", "file1")
- if "dir2-link" in group1:
- t.expect_addition("include/file2.h")
- t.expect_content("include/file2.h", "file2")
- ignore_config(t)
- t.expect_nothing_more()
- t.run_build_system(group2)
- if "dir1-link" in group2:
- if "dir1-link" not in group1:
- t.expect_addition("include/file1.h")
- else:
- # When a directory is split the link needs to be recreated.
- # On Windows, the test system checks the mod time of the
- # link rather than the link target, so this may be seen as
- # an update.
- t.ignore_touch("include/file1.h")
- t.expect_content("include/file1.h", "file1")
- else:
- t.ignore_removal("include/file1.h")
- if "dir2-link" in group2:
- if "dir2-link" not in group1:
- t.expect_addition("include/file2.h")
- else:
- t.ignore_touch("include/file2.h")
- t.expect_content("include/file2.h", "file2")
- else:
- t.ignore_removal("include/file2.h")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_merge_existing_all():
- test_merge_existing(["dir1-link"], ["dir2-link"])
- test_merge_existing(["dir2-link"], ["dir1-link"])
- test_merge_existing(["dir1-link"], ["dir1-link", "dir2-link"])
- test_merge_existing(["dir2-link"], ["dir1-link", "dir2-link"])
- def test_merge_recursive():
- "Test merging several directories including common prefixes"
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- link-directory dir3-link : src/dir3/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/file2.h", "file2")
- t.write("src/dir2/include/nested/file3.h", "file3")
- t.write("src/dir3/include/nested/file4.h", "file4")
- t.run_build_system()
- t.expect_addition("include/file1.h")
- t.expect_content("include/file1.h", "file1")
- t.expect_addition("include/file2.h")
- t.expect_content("include/file2.h", "file2")
- t.expect_addition("include/nested/file3.h")
- t.expect_content("include/nested/file3.h", "file3")
- t.expect_addition("include/nested/file4.h")
- t.expect_content("include/nested/file4.h", "file4")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_merge_recursive_existing(group1, group2):
- "Test merging several directories including common prefixes."
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- link-directory dir3-link : src/dir3/include : <location>. ;
- link-directory dir4-link : src/dir4/include : <location>. ;
- link-directory dir5-link : src/dir5/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/nested/file2.h", "file2")
- t.write("src/dir3/include/nested/file3.h", "file3")
- t.write("src/dir4/include/nested/xxx/yyy/file4.h", "file4")
- t.write("src/dir5/include/nested/xxx/yyy/file5.h", "file5")
- t.run_build_system(group1)
- t.run_build_system(group2 + ["-d+12"])
- def check_file(target, file):
- if target in group2:
- if target in group1:
- t.ignore_touch(file)
- else:
- t.expect_addition(file)
- check_file("dir1-link", "include/file1.h")
- check_file("dir2-link", "include/nested/file2.h")
- check_file("dir3-link", "include/nested/file3.h")
- check_file("dir4-link", "include/nested/xxx/yyy/file4.h")
- check_file("dir5-link", "include/nested/xxx/yyy/file5.h")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_merge_recursive_existing_all():
- # These should create a link
- test_merge_recursive_existing(["dir2-link"], ["dir2-link", "dir1-link"])
- test_merge_recursive_existing(["dir2-link"], ["dir1-link", "dir2-link"])
- # These should create a directory
- test_merge_recursive_existing(["dir2-link"], ["dir2-link", "dir3-link"])
- test_merge_recursive_existing(["dir2-link"], ["dir3-link", "dir2-link"])
- # It should work even if we have to create many intermediate subdirectories
- test_merge_recursive_existing(["dir4-link"], ["dir4-link", "dir5-link"])
- test_merge_recursive_existing(["dir4-link"], ["dir5-link", "dir4-link"])
- def test_include_scan():
- """Make sure that the #include scanner finds the headers"""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- obj test : test.cpp :
- <include>include
- <implicit-dependency>dir1-link
- <implicit-dependency>dir2-link ;
- """)
- t.write("src/dir1/include/file1.h", "#include <file2.h>\n")
- t.write("src/dir2/include/file2.h", "int f();\n")
- t.write("test.cpp", """\
- #include <file1.h>
- int main() { f(); }
- """);
- t.run_build_system(["test"])
- t.expect_addition("bin/$toolset/debug*/test.obj")
- t.run_build_system()
- t.expect_nothing_more()
- t.cleanup()
- def test_include_scan_merge_existing():
- """Make sure that files are replaced if needed when merging in
- a new directory"""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- obj test : test.cpp :
- <include>include
- <implicit-dependency>dir1-link
- <implicit-dependency>dir2-link ;
- """)
- t.write("src/dir1/include/file1.h", "int f();")
- t.write("src/dir2/include/file2.h", "#include <file1.h>")
- t.write("test.cpp", """\
- #include <file2.h>
- int main() { f(); }
- """)
- t.run_build_system(["dir2-link"])
- t.run_build_system(["test"])
- t.expect_addition("include/file1.h")
- t.expect_addition("bin/$toolset/debug*/test.obj")
- t.ignore_touch("include/file2.h")
- t.expect_nothing_more()
- t.cleanup()
- def test_update_file_link(params1, params2):
- """Tests the behavior of updates when changing the link mode.
- The link needs to be updated iff the original was a copy."""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- import project ;
- import property-set ;
- import modules ;
- if --no-symlinks in [ modules.peek : ARGV ]
- {
- modules.poke link : .can-symlink : false ;
- }
- if --no-hardlinks in [ modules.peek : ARGV ]
- {
- modules.poke link : .can-hardlink : false ;
- }
- .project = [ project.current ] ;
- .has-files = [ glob include/file1.h ] ;
- rule can-link ( properties * ) {
- if ( ! [ link.can-symlink $(.project) ] ) &&
- ( ! [ link.can-hardlink $(.project) ] )
- {
- ECHO links unsupported ;
- }
- }
- # Use two directories so that we link to individual files.
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- alias check-linking : : <conditional>@can-link ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/file2.h", "file2")
- t.run_build_system(params1)
- ignore_config(t)
- t.expect_addition("include/file1.h")
- t.expect_addition("include/file2.h")
- t.expect_nothing_more()
- using_links = "links unsupported" not in t.stdout()
- t.touch("src/dir1/include/file1.h")
- t.run_build_system(params2)
- if not using_links: t.expect_touch("include/file1.h")
- ignore_config(t)
- t.expect_nothing_more()
- t.cleanup()
- def test_update_file_link_all():
- """Test all nine possible combinations of two runs."""
- possible_args = [[], ["--no-symlinks"], ["--no-symlinks", "--no-hardlinks"]]
- for arg1 in possible_args:
- for arg2 in possible_args:
- test_update_file_link(arg1, arg2)
- def test_error_duplicate():
- """Test that linking a single file from
- multiple sources causes a hard error."""
- t = BoostBuild.Tester()
- t.write("jamroot.jam", """\
- import link ;
- link-directory dir1-link : src/dir1/include : <location>. ;
- link-directory dir2-link : src/dir2/include : <location>. ;
- """)
- t.write("src/dir1/include/file1.h", "file1")
- t.write("src/dir2/include/file1.h", "file2")
- t.run_build_system(status=1)
- t.expect_output_lines(
- ["error: Cannot create link include/file1.h to src/dir2/include/file1.h.",
- "error: Link previously defined to another file, src/dir1/include/file1.h."])
- t.cleanup()
- test_basic()
- test_merge_two()
- test_merge_existing_all()
- test_merge_recursive()
- test_merge_recursive_existing_all()
- test_include_scan()
- test_include_scan_merge_existing()
- test_update_file_link_all()
- test_error_duplicate()
|