| 
														
															@@ -1,12 +1,20 @@ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import json 
														 | 
														
														 | 
														
															 import json 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import os 
														 | 
														
														 | 
														
															 import os 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from pathlib import Path 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import stat 
														 | 
														
														 | 
														
															 import stat 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 import time 
														 | 
														
														 | 
														
															 import time 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ...constants import *  # NOQA 
														 | 
														
														 | 
														
															 from ...constants import *  # NOQA 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from .. import are_symlinks_supported, are_hardlinks_supported 
														 | 
														
														 | 
														
															 from .. import are_symlinks_supported, are_hardlinks_supported 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 from ...platformflags import is_win32, is_darwin 
														 | 
														
														 | 
														
															 from ...platformflags import is_win32, is_darwin 
														 | 
													
												
											
												
													
														| 
														 | 
														
															-from . import cmd, create_regular_file, RK_ENCRYPTION, assert_line_exists, generate_archiver_tests 
														 | 
														
														 | 
														
															 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+from . import ( 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    cmd, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    create_regular_file, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    RK_ENCRYPTION, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    assert_line_exists, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    generate_archiver_tests, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    assert_line_not_exists, 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 pytest_generate_tests = lambda metafunc: generate_archiver_tests(metafunc, kinds="local,remote,binary")  # NOQA 
														 | 
														
														 | 
														
															 pytest_generate_tests = lambda metafunc: generate_archiver_tests(metafunc, kinds="local,remote,binary")  # NOQA 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -19,6 +27,7 @@ def test_basic_functionality(archivers, request): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     create_regular_file(archiver.input_path, "file_removed", size=256) 
														 | 
														
														 | 
														
															     create_regular_file(archiver.input_path, "file_removed", size=256) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     create_regular_file(archiver.input_path, "file_removed2", size=512) 
														 | 
														
														 | 
														
															     create_regular_file(archiver.input_path, "file_removed2", size=512) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     create_regular_file(archiver.input_path, "file_replaced", size=1024) 
														 | 
														
														 | 
														
															     create_regular_file(archiver.input_path, "file_replaced", size=1024) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    create_regular_file(archiver.input_path, "file_touched", size=128) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.mkdir("input/dir_replaced_with_file") 
														 | 
														
														 | 
														
															     os.mkdir("input/dir_replaced_with_file") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.chmod("input/dir_replaced_with_file", stat.S_IFDIR | 0o755) 
														 | 
														
														 | 
														
															     os.chmod("input/dir_replaced_with_file", stat.S_IFDIR | 0o755) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.mkdir("input/dir_removed") 
														 | 
														
														 | 
														
															     os.mkdir("input/dir_removed") 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -44,6 +53,7 @@ def test_basic_functionality(archivers, request): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     create_regular_file(archiver.input_path, "file_replaced", contents=b"0" * 4096) 
														 | 
														
														 | 
														
															     create_regular_file(archiver.input_path, "file_replaced", contents=b"0" * 4096) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.unlink("input/file_removed") 
														 | 
														
														 | 
														
															     os.unlink("input/file_removed") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.unlink("input/file_removed2") 
														 | 
														
														 | 
														
															     os.unlink("input/file_removed2") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+    Path("input/file_touched").touch() 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.rmdir("input/dir_replaced_with_file") 
														 | 
														
														 | 
														
															     os.rmdir("input/dir_replaced_with_file") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     create_regular_file(archiver.input_path, "dir_replaced_with_file", size=8192) 
														 | 
														
														 | 
														
															     create_regular_file(archiver.input_path, "dir_replaced_with_file", size=8192) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															     os.chmod("input/dir_replaced_with_file", stat.S_IFREG | 0o755) 
														 | 
														
														 | 
														
															     os.chmod("input/dir_replaced_with_file", stat.S_IFREG | 0o755) 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -102,6 +112,15 @@ def test_basic_functionality(archivers, request): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # pointing to the file is not changed. 
														 | 
														
														 | 
														
															         # pointing to the file is not changed. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         change = "modified.*0 B" if can_compare_ids else r"modified:  \(can't get size\)" 
														 | 
														
														 | 
														
															         change = "modified.*0 B" if can_compare_ids else r"modified:  \(can't get size\)" 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert_line_exists(lines, f"{change}.*input/empty") 
														 | 
														
														 | 
														
															         assert_line_exists(lines, f"{change}.*input/empty") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # Do not show a 0 byte change for a file whose contents weren't modified. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        assert_line_not_exists(lines, "0 B.*input/file_touched") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if not content_only: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            assert_line_exists(lines, "[cm]time:.*input/file_touched") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        else: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            # And if we're doing content-only, don't show the file at all. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            assert "input/file_touched" not in output 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if are_hardlinks_supported(): 
														 | 
														
														 | 
														
															         if are_hardlinks_supported(): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             assert_line_exists(lines, f"{change}.*input/hardlink_contents_changed") 
														 | 
														
														 | 
														
															             assert_line_exists(lines, f"{change}.*input/hardlink_contents_changed") 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if are_symlinks_supported(): 
														 | 
														
														 | 
														
															         if are_symlinks_supported(): 
														 | 
													
												
											
										
											
												
													
														 | 
														
															@@ -150,6 +169,17 @@ def test_basic_functionality(archivers, request): 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # File unchanged 
														 | 
														
														 | 
														
															         # File unchanged 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         assert not any(get_changes("input/file_unchanged", joutput)) 
														 | 
														
														 | 
														
															         assert not any(get_changes("input/file_unchanged", joutput)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															  
														 | 
														
														 | 
														
															  
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        # Do not show a 0 byte change for a file whose contents weren't modified. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        unexpected = {"type": "modified", "added": 0, "removed": 0} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        assert unexpected not in get_changes("input/file_touched", joutput) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        if not content_only: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            # on win32, ctime is the file creation time and does not change. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            expected = {"mtime"} if is_win32 else {"mtime", "ctime"} 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            assert expected.issubset({c["type"] for c in get_changes("input/file_touched", joutput)}) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+        else: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            # And if we're doing content-only, don't show the file at all. 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+            assert not any(get_changes("input/file_touched", joutput)) 
														 | 
													
												
											
												
													
														| 
														 | 
														
															 
														 | 
														
														 | 
														
															+ 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         # Directory replaced with a regular file 
														 | 
														
														 | 
														
															         # Directory replaced with a regular file 
														 | 
													
												
											
												
													
														| 
														 | 
														
															         if "BORG_TESTS_IGNORE_MODES" not in os.environ and not is_win32 and not content_only: 
														 | 
														
														 | 
														
															         if "BORG_TESTS_IGNORE_MODES" not in os.environ and not is_win32 and not content_only: 
														 | 
													
												
											
												
													
														| 
														 | 
														
															             assert {"type": "changed mode", "item1": "drwxr-xr-x", "item2": "-rwxr-xr-x"} in get_changes( 
														 | 
														
														 | 
														
															             assert {"type": "changed mode", "item1": "drwxr-xr-x", "item2": "-rwxr-xr-x"} in get_changes( 
														 |