|
32 | 32 | @author: Maxime Boissonneault (Compute Canada, Universite Laval) |
33 | 33 | """ |
34 | 34 | import datetime |
| 35 | +import filecmp |
35 | 36 | import glob |
36 | 37 | import logging |
37 | 38 | import os |
|
51 | 52 | from easybuild.tools.config import IGNORE, ERROR, build_option, update_build_option |
52 | 53 | from easybuild.tools.multidiff import multidiff |
53 | 54 | from easybuild.tools.py2vs3 import StringIO, std_urllib |
| 55 | +from easybuild.tools.run import run_cmd |
| 56 | +from easybuild.tools.systemtools import LINUX, get_os_type |
54 | 57 |
|
55 | 58 |
|
56 | 59 | class FileToolsTest(EnhancedTestCase): |
@@ -1912,6 +1915,47 @@ def test_copy_file(self): |
1912 | 1915 | # However, if we add 'force_in_dry_run=True' it should throw an exception |
1913 | 1916 | self.assertErrorRegex(EasyBuildError, "Could not copy *", ft.copy_file, src, target, force_in_dry_run=True) |
1914 | 1917 |
|
| 1918 | + def test_copy_file_xattr(self): |
| 1919 | + """Test copying a file with extended attributes using copy_file.""" |
| 1920 | + # test copying a read-only files with extended attributes set |
| 1921 | + # first, create a special file with extended attributes |
| 1922 | + special_file = os.path.join(self.test_prefix, 'special.txt') |
| 1923 | + ft.write_file(special_file, 'special') |
| 1924 | + # make read-only, and set extended attributes |
| 1925 | + attr = ft.which('attr') |
| 1926 | + xattr = ft.which('xattr') |
| 1927 | + # try to attr (Linux) or xattr (macOS) to set extended attributes foo=bar |
| 1928 | + cmd = None |
| 1929 | + if attr: |
| 1930 | + cmd = "attr -s foo -V bar %s" % special_file |
| 1931 | + elif xattr: |
| 1932 | + cmd = "xattr -w foo bar %s" % special_file |
| 1933 | + |
| 1934 | + if cmd: |
| 1935 | + (_, ec) = run_cmd(cmd, simple=False, log_all=False, log_ok=False) |
| 1936 | + |
| 1937 | + # need to make file read-only after setting extended attribute |
| 1938 | + ft.adjust_permissions(special_file, stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH, add=False) |
| 1939 | + |
| 1940 | + # only proceed if setting extended attribute worked |
| 1941 | + if ec == 0: |
| 1942 | + target = os.path.join(self.test_prefix, 'copy.txt') |
| 1943 | + ft.copy_file(special_file, target) |
| 1944 | + self.assertTrue(os.path.exists(target)) |
| 1945 | + self.assertTrue(filecmp.cmp(special_file, target, shallow=False)) |
| 1946 | + |
| 1947 | + # only verify wheter extended attributes were also copied on Linux, |
| 1948 | + # since shutil.copy2 doesn't copy them on macOS; |
| 1949 | + # see warning at https://docs.python.org/3/library/shutil.html |
| 1950 | + if get_os_type() == LINUX: |
| 1951 | + if attr: |
| 1952 | + cmd = "attr -g foo %s" % target |
| 1953 | + else: |
| 1954 | + cmd = "xattr -l %s" % target |
| 1955 | + (out, ec) = run_cmd(cmd, simple=False, log_all=False, log_ok=False) |
| 1956 | + self.assertEqual(ec, 0) |
| 1957 | + self.assertTrue(out.endswith('\nbar\n')) |
| 1958 | + |
1915 | 1959 | def test_copy_files(self): |
1916 | 1960 | """Test copy_files function.""" |
1917 | 1961 | test_ecs = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'easyconfigs', 'test_ecs') |
|
0 commit comments