Changeset c715e0d in trunk
- Timestamp:
- 2016-05-04T15:04:51Z (9 years ago)
- Branches:
- master
- Children:
- d1d9884
- Parents:
- 9402b40d (diff), fa418a7 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent. - Location:
- src/allmydata
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/allmydata/test/test_util.py ¶
r9402b40d rc715e0d 498 498 saved_cwd = os.path.normpath(os.getcwdu()) 499 499 abspath_cwd = fileutil.abspath_expanduser_unicode(u".") 500 abspath_cwd_notlong = fileutil.abspath_expanduser_unicode(u".", long_path=False) 500 501 self.failUnless(isinstance(saved_cwd, unicode), saved_cwd) 501 502 self.failUnless(isinstance(abspath_cwd, unicode), abspath_cwd) … … 504 505 else: 505 506 self.failUnlessReallyEqual(abspath_cwd, saved_cwd) 507 self.failUnlessReallyEqual(abspath_cwd_notlong, saved_cwd) 506 508 507 509 self.failUnlessReallyEqual(fileutil.to_windows_long_path(u"\\\\?\\foo"), u"\\\\?\\foo") … … 532 534 self.failUnlessReallyEqual(baz[4], bar[4]) # same drive 533 535 536 baz_notlong = fileutil.abspath_expanduser_unicode(u"\\baz", long_path=False) 537 self.failIf(baz_notlong.startswith(u"\\\\?\\"), baz_notlong) 538 self.failUnlessReallyEqual(baz_notlong[1 :], u":\\baz") 539 540 bar_notlong = fileutil.abspath_expanduser_unicode(u"\\bar", base=baz_notlong, long_path=False) 541 self.failIf(bar_notlong.startswith(u"\\\\?\\"), bar_notlong) 542 self.failUnlessReallyEqual(bar_notlong[1 :], u":\\bar") 543 # not u":\\baz\\bar", because \bar is absolute on the current drive. 544 545 self.failUnlessReallyEqual(baz_notlong[0], bar_notlong[0]) # same drive 546 534 547 self.failIfIn(u"~", fileutil.abspath_expanduser_unicode(u"~")) 548 self.failIfIn(u"~", fileutil.abspath_expanduser_unicode(u"~", long_path=False)) 535 549 536 550 cwds = ['cwd'] … … 548 562 uabspath = fileutil.abspath_expanduser_unicode(upath) 549 563 self.failUnless(isinstance(uabspath, unicode), uabspath) 564 565 uabspath_notlong = fileutil.abspath_expanduser_unicode(upath, long_path=False) 566 self.failUnless(isinstance(uabspath_notlong, unicode), uabspath_notlong) 550 567 finally: 551 568 os.chdir(saved_cwd) 569 570 def test_make_dirs_with_absolute_mode(self): 571 if sys.platform == 'win32': 572 raise unittest.SkipTest("Permissions don't work the same on windows.") 573 574 workdir = fileutil.abspath_expanduser_unicode(u"test_make_dirs_with_absolute_mode") 575 fileutil.make_dirs(workdir) 576 abspath = fileutil.abspath_expanduser_unicode(u"a/b/c/d", base=workdir) 577 fileutil.make_dirs_with_absolute_mode(workdir, abspath, 0766) 578 new_mode = os.stat(os.path.join(workdir, "a", "b", "c", "d")).st_mode & 0777 579 self.failUnlessEqual(new_mode, 0766) 580 new_mode = os.stat(os.path.join(workdir, "a", "b", "c")).st_mode & 0777 581 self.failUnlessEqual(new_mode, 0766) 582 new_mode = os.stat(os.path.join(workdir, "a", "b")).st_mode & 0777 583 self.failUnlessEqual(new_mode, 0766) 584 new_mode = os.stat(os.path.join(workdir,"a")).st_mode & 0777 585 self.failUnlessEqual(new_mode, 0766) 586 new_mode = os.stat(workdir).st_mode & 0777 587 self.failIfEqual(new_mode, 0766) 552 588 553 589 def test_create_long_path(self): … … 604 640 disk = fileutil.get_disk_stats('.', 2**128) 605 641 self.failUnlessEqual(disk['avail'], 0) 642 643 def test_get_pathinfo(self): 644 basedir = "util/FileUtil/test_get_pathinfo" 645 fileutil.make_dirs(basedir) 646 647 # create a directory 648 self.mkdir(basedir, "a") 649 dirinfo = fileutil.get_pathinfo(basedir) 650 self.failUnlessTrue(dirinfo.isdir) 651 self.failUnlessTrue(dirinfo.exists) 652 self.failUnlessFalse(dirinfo.isfile) 653 self.failUnlessFalse(dirinfo.islink) 654 655 # create a file 656 f = os.path.join(basedir, "1.txt") 657 fileutil.write(f, "a"*10) 658 fileinfo = fileutil.get_pathinfo(f) 659 self.failUnlessTrue(fileinfo.isfile) 660 self.failUnlessTrue(fileinfo.exists) 661 self.failUnlessFalse(fileinfo.isdir) 662 self.failUnlessFalse(fileinfo.islink) 663 self.failUnlessEqual(fileinfo.size, 10) 664 665 # path at which nothing exists 666 dnename = os.path.join(basedir, "doesnotexist") 667 now = time.time() 668 dneinfo = fileutil.get_pathinfo(dnename, now=now) 669 self.failUnlessFalse(dneinfo.exists) 670 self.failUnlessFalse(dneinfo.isfile) 671 self.failUnlessFalse(dneinfo.isdir) 672 self.failUnlessFalse(dneinfo.islink) 673 self.failUnlessEqual(dneinfo.size, None) 674 self.failUnlessEqual(dneinfo.mtime, now) 675 self.failUnlessEqual(dneinfo.ctime, now) 676 677 def test_get_pathinfo_symlink(self): 678 if not hasattr(os, 'symlink'): 679 raise unittest.SkipTest("can't create symlinks on this platform") 680 681 basedir = "util/FileUtil/test_get_pathinfo" 682 fileutil.make_dirs(basedir) 683 684 f = os.path.join(basedir, "1.txt") 685 fileutil.write(f, "a"*10) 686 687 # create a symlink pointing to 1.txt 688 slname = os.path.join(basedir, "linkto1.txt") 689 os.symlink(f, slname) 690 symlinkinfo = fileutil.get_pathinfo(slname) 691 self.failUnlessTrue(symlinkinfo.islink) 692 self.failUnlessTrue(symlinkinfo.exists) 693 self.failUnlessFalse(symlinkinfo.isfile) 694 self.failUnlessFalse(symlinkinfo.isdir) 695 606 696 607 697 class PollMixinTests(unittest.TestCase): -
TabularUnified src/allmydata/util/fileutil.py ¶
r9402b40d rc715e0d 4 4 5 5 import sys, exceptions, os, stat, tempfile, time, binascii 6 from collections import namedtuple 7 from errno import ENOENT 6 8 7 9 if sys.platform == "win32": 8 10 from ctypes import WINFUNCTYPE, WinError, windll, POINTER, byref, c_ulonglong, \ 9 11 create_unicode_buffer, get_last_error 10 from ctypes.wintypes import BOOL, DWORD, LPCWSTR, LPWSTR 12 from ctypes.wintypes import BOOL, DWORD, LPCWSTR, LPWSTR, LPVOID, HANDLE 11 13 12 14 from twisted.python import log 13 15 14 16 from pycryptopp.cipher.aes import AES 17 18 from allmydata.util.assertutil import _assert 15 19 16 20 … … 141 145 self.file.truncate(newsize) 142 146 147 def make_dirs_with_absolute_mode(parent, dirname, mode): 148 """ 149 Make directory `dirname` and chmod it to `mode` afterwards. 150 We chmod all parent directories of `dirname` until we reach 151 `parent`. 152 """ 153 precondition_abspath(parent) 154 precondition_abspath(dirname) 155 if not is_ancestor_path(parent, dirname): 156 raise AssertionError("dirname must be a descendant of parent") 157 158 make_dirs(dirname) 159 while dirname != parent: 160 os.chmod(dirname, mode) 161 # FIXME: doesn't seem to work on Windows for long paths 162 old_dirname, dirname = dirname, os.path.dirname(dirname) 163 _assert(len(dirname) < len(old_dirname), dirname=dirname, old_dirname=old_dirname) 164 165 def is_ancestor_path(parent, dirname): 166 while dirname != parent: 167 # FIXME: doesn't seem to work on Windows for long paths 168 old_dirname, dirname = dirname, os.path.dirname(dirname) 169 if len(dirname) >= len(old_dirname): 170 return False 171 return True 143 172 144 173 def make_dirs(dirname, mode=0777): … … 280 309 pass 281 310 282 def abspath_expanduser_unicode(path, base=None ):311 def abspath_expanduser_unicode(path, base=None, long_path=True): 283 312 """ 284 313 Return the absolute version of a path. If 'base' is given and 'path' is relative, … … 287 316 corresponding to an absolute path as returned by a previous call to 288 317 abspath_expanduser_unicode. 318 On Windows, the result will be a long path unless long_path is given as False. 289 319 """ 290 320 if not isinstance(path, unicode): 291 321 raise AssertionError("paths must be Unicode strings") 292 if base is not None :322 if base is not None and long_path: 293 323 precondition_abspath(base) 294 324 … … 317 347 path = os.path.normpath(path) 318 348 319 if sys.platform == "win32" :349 if sys.platform == "win32" and long_path: 320 350 path = to_windows_long_path(path) 321 351 … … 515 545 log.msg("OS call to get disk statistics failed") 516 546 return 0 547 548 549 if sys.platform == "win32": 550 # <http://msdn.microsoft.com/en-us/library/aa363858%28v=vs.85%29.aspx> 551 CreateFileW = WINFUNCTYPE( 552 HANDLE, LPCWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE, 553 use_last_error=True 554 )(("CreateFileW", windll.kernel32)) 555 556 GENERIC_WRITE = 0x40000000 557 FILE_SHARE_READ = 0x00000001 558 FILE_SHARE_WRITE = 0x00000002 559 OPEN_EXISTING = 3 560 INVALID_HANDLE_VALUE = 0xFFFFFFFF 561 562 # <http://msdn.microsoft.com/en-us/library/aa364439%28v=vs.85%29.aspx> 563 FlushFileBuffers = WINFUNCTYPE( 564 BOOL, HANDLE, 565 use_last_error=True 566 )(("FlushFileBuffers", windll.kernel32)) 567 568 # <http://msdn.microsoft.com/en-us/library/ms724211%28v=vs.85%29.aspx> 569 CloseHandle = WINFUNCTYPE( 570 BOOL, HANDLE, 571 use_last_error=True 572 )(("CloseHandle", windll.kernel32)) 573 574 # <http://social.msdn.microsoft.com/forums/en-US/netfxbcl/thread/4465cafb-f4ed-434f-89d8-c85ced6ffaa8/> 575 def flush_volume(path): 576 abspath = os.path.realpath(path) 577 if abspath.startswith("\\\\?\\"): 578 abspath = abspath[4 :] 579 drive = os.path.splitdrive(abspath)[0] 580 581 print "flushing %r" % (drive,) 582 hVolume = CreateFileW(u"\\\\.\\" + drive, 583 GENERIC_WRITE, 584 FILE_SHARE_READ | FILE_SHARE_WRITE, 585 None, 586 OPEN_EXISTING, 587 0, 588 None 589 ) 590 if hVolume == INVALID_HANDLE_VALUE: 591 raise WinError(get_last_error()) 592 593 if FlushFileBuffers(hVolume) == 0: 594 raise WinError(get_last_error()) 595 596 CloseHandle(hVolume) 597 else: 598 def flush_volume(path): 599 # use sync()? 600 pass 601 602 603 class ConflictError(Exception): 604 pass 605 606 class UnableToUnlinkReplacementError(Exception): 607 pass 608 609 def reraise(wrapper): 610 _, exc, tb = sys.exc_info() 611 wrapper_exc = wrapper("%s: %s" % (exc.__class__.__name__, exc)) 612 raise wrapper_exc.__class__, wrapper_exc, tb 613 614 if sys.platform == "win32": 615 # <https://msdn.microsoft.com/en-us/library/windows/desktop/aa365512%28v=vs.85%29.aspx> 616 ReplaceFileW = WINFUNCTYPE( 617 BOOL, LPCWSTR, LPCWSTR, LPCWSTR, DWORD, LPVOID, LPVOID, 618 use_last_error=True 619 )(("ReplaceFileW", windll.kernel32)) 620 621 REPLACEFILE_IGNORE_MERGE_ERRORS = 0x00000002 622 623 # <https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382%28v=vs.85%29.aspx> 624 ERROR_FILE_NOT_FOUND = 2 625 626 def rename_no_overwrite(source_path, dest_path): 627 os.rename(source_path, dest_path) 628 629 def replace_file(replaced_path, replacement_path, backup_path): 630 precondition_abspath(replaced_path) 631 precondition_abspath(replacement_path) 632 precondition_abspath(backup_path) 633 634 r = ReplaceFileW(replaced_path, replacement_path, backup_path, 635 REPLACEFILE_IGNORE_MERGE_ERRORS, None, None) 636 if r == 0: 637 # The UnableToUnlinkReplacementError case does not happen on Windows; 638 # all errors should be treated as signalling a conflict. 639 err = get_last_error() 640 if err != ERROR_FILE_NOT_FOUND: 641 raise ConflictError("WinError: %s" % (WinError(err),)) 642 643 try: 644 rename_no_overwrite(replacement_path, replaced_path) 645 except EnvironmentError: 646 reraise(ConflictError) 647 else: 648 def rename_no_overwrite(source_path, dest_path): 649 # link will fail with EEXIST if there is already something at dest_path. 650 os.link(source_path, dest_path) 651 try: 652 os.unlink(source_path) 653 except EnvironmentError: 654 reraise(UnableToUnlinkReplacementError) 655 656 def replace_file(replaced_path, replacement_path, backup_path): 657 precondition_abspath(replaced_path) 658 precondition_abspath(replacement_path) 659 precondition_abspath(backup_path) 660 661 if not os.path.exists(replacement_path): 662 raise ConflictError("Replacement file not found: %r" % (replacement_path,)) 663 664 try: 665 os.rename(replaced_path, backup_path) 666 except OSError as e: 667 if e.errno != ENOENT: 668 raise 669 try: 670 rename_no_overwrite(replacement_path, replaced_path) 671 except EnvironmentError: 672 reraise(ConflictError) 673 674 PathInfo = namedtuple('PathInfo', 'isdir isfile islink exists size mtime ctime') 675 676 def get_pathinfo(path_u, now=None): 677 try: 678 statinfo = os.lstat(path_u) 679 mode = statinfo.st_mode 680 return PathInfo(isdir =stat.S_ISDIR(mode), 681 isfile=stat.S_ISREG(mode), 682 islink=stat.S_ISLNK(mode), 683 exists=True, 684 size =statinfo.st_size, 685 mtime =statinfo.st_mtime, 686 ctime =statinfo.st_ctime, 687 ) 688 except OSError as e: 689 if e.errno == ENOENT: 690 if now is None: 691 now = time.time() 692 return PathInfo(isdir =False, 693 isfile=False, 694 islink=False, 695 exists=False, 696 size =None, 697 mtime =now, 698 ctime =now, 699 ) 700 raise
Note: See TracChangeset
for help on using the changeset viewer.