Commit 53e8bd02 by willmcgugan

test fixes for windoze

parent e24d7a4a
...@@ -15,7 +15,7 @@ Serves the contents of PATH with one of a number of methods""" ...@@ -15,7 +15,7 @@ Serves the contents of PATH with one of a number of methods"""
optparse = super(FSServe, self).get_optparse() optparse = super(FSServe, self).get_optparse()
optparse.add_option('-t', '--type', dest='type', type="string", default="http", optparse.add_option('-t', '--type', dest='type', type="string", default="http",
help="Server type to create (http, rpc, sftp)", metavar="TYPE") help="Server type to create (http, rpc, sftp)", metavar="TYPE")
optparse.add_option('-a', '--addr', dest='addr', type="string", default="localhost", optparse.add_option('-a', '--addr', dest='addr', type="string", default="127.0.0.1",
help="Server address", metavar="ADDR") help="Server address", metavar="ADDR")
optparse.add_option('-p', '--port', dest='port', type="int", optparse.add_option('-p', '--port', dest='port', type="int",
help="Port number", metavar="") help="Port number", metavar="")
......
...@@ -42,7 +42,7 @@ Recursively display the contents of PATH in an ascii tree""" ...@@ -42,7 +42,7 @@ Recursively display the contents of PATH in an ascii tree"""
print_fs(fs, path or '', print_fs(fs, path or '',
file_out=self.output_file, file_out=self.output_file,
max_levels=options.depth, max_levels=options.depth,
terminal_colors=self.is_terminal(), terminal_colors=self.terminal_colors,
hide_dotfiles=not options.all, hide_dotfiles=not options.all,
dirs_first=options.dirsfirst) dirs_first=options.dirsfirst)
......
import warnings
warnings.filterwarnings("ignore")
import sys import sys
from optparse import OptionParser from optparse import OptionParser
from fs.opener import opener, OpenerError, Opener from fs.opener import opener, OpenerError, Opener
......
...@@ -549,7 +549,7 @@ class _FTPFile(object): ...@@ -549,7 +549,7 @@ class _FTPFile(object):
self._lock = threading.RLock() self._lock = threading.RLock()
self.ftpfs = ftpfs self.ftpfs = ftpfs
self.ftp = ftp self.ftp = ftp
self.path = path self.path = normpath(path)
self.mode = mode self.mode = mode
self.read_pos = 0 self.read_pos = 0
self.write_pos = 0 self.write_pos = 0
...@@ -559,9 +559,7 @@ class _FTPFile(object): ...@@ -559,9 +559,7 @@ class _FTPFile(object):
self.file_size = ftpfs.getsize(path) self.file_size = ftpfs.getsize(path)
self.conn = None self.conn = None
path = _encode(abspath(path)) self._start_file(mode, _encode(self.path))
#self._lock = ftpfs._lock
self._start_file(mode, path)
@fileftperrors @fileftperrors
def _start_file(self, mode, path): def _start_file(self, mode, path):
...@@ -569,15 +567,15 @@ class _FTPFile(object): ...@@ -569,15 +567,15 @@ class _FTPFile(object):
self.write_pos = 0 self.write_pos = 0
if 'r' in mode: if 'r' in mode:
self.ftp.voidcmd('TYPE I') self.ftp.voidcmd('TYPE I')
self.conn = self.ftp.transfercmd('RETR '+path, None) self.conn = self.ftp.transfercmd('RETR ' + path, None)
else:#if 'w' in mode or 'a' in mode: else:#if 'w' in mode or 'a' in mode:
self.ftp.voidcmd('TYPE I') self.ftp.voidcmd('TYPE I')
if 'a' in mode: if 'a' in mode:
self.write_pos = self.file_size self.write_pos = self.file_size
self.conn = self.ftp.transfercmd('APPE '+path) self.conn = self.ftp.transfercmd('APPE ' + path)
else: else:
self.conn = self.ftp.transfercmd('STOR '+path) self.conn = self.ftp.transfercmd('STOR ' + path)
@fileftperrors @fileftperrors
def read(self, size=None): def read(self, size=None):
...@@ -765,8 +763,6 @@ class _FTPFile(object): ...@@ -765,8 +763,6 @@ class _FTPFile(object):
yield line yield line
append(c) append(c)
def ftperrors(f): def ftperrors(f):
@wraps(f) @wraps(f)
def deco(self, *args, **kwargs): def deco(self, *args, **kwargs):
...@@ -884,7 +880,7 @@ class FTPFS(FS): ...@@ -884,7 +880,7 @@ class FTPFS(FS):
@synchronize @synchronize
def _readdir(self, path): def _readdir(self, path):
path = normpath(path) path = abspath(normpath(path))
if self.dircache.count: if self.dircache.count:
cached_dirlist = self.dircache.get(path) cached_dirlist = self.dircache.get(path)
if cached_dirlist is not None: if cached_dirlist is not None:
...@@ -901,7 +897,6 @@ class FTPFS(FS): ...@@ -901,7 +897,6 @@ class FTPFS(FS):
info = info.__dict__ info = info.__dict__
if info['name'] not in ('.', '..'): if info['name'] not in ('.', '..'):
dirlist[info['name']] = info dirlist[info['name']] = info
try: try:
self.ftp.dir(_encode(path), on_line) self.ftp.dir(_encode(path), on_line)
except error_reply: except error_reply:
...@@ -925,7 +920,7 @@ class FTPFS(FS): ...@@ -925,7 +920,7 @@ class FTPFS(FS):
else: else:
remove_paths = [] remove_paths = []
dircache = self.dircache dircache = self.dircache
paths = [normpath(path) for path in paths] paths = [normpath(abspath(path)) for path in paths]
for cached_path in dircache.keys(): for cached_path in dircache.keys():
for path in paths: for path in paths:
if isbase(cached_path, path): if isbase(cached_path, path):
...@@ -1046,6 +1041,7 @@ class FTPFS(FS): ...@@ -1046,6 +1041,7 @@ class FTPFS(FS):
@ftperrors @ftperrors
def open(self, path, mode='r'): def open(self, path, mode='r'):
path = normpath(path)
mode = mode.lower() mode = mode.lower()
if self.isdir(path): if self.isdir(path):
raise ResourceInvalidError(path) raise ResourceInvalidError(path)
...@@ -1068,8 +1064,9 @@ class FTPFS(FS): ...@@ -1068,8 +1064,9 @@ class FTPFS(FS):
@ftperrors @ftperrors
def getcontents(self, path): def getcontents(self, path):
path = normpath(path)
contents = StringIO() contents = StringIO()
self.ftp.retrbinary('RETR %s' % _encode(normpath(path)), contents.write, blocksize=1024*64) self.ftp.retrbinary('RETR %s' % _encode(path), contents.write, blocksize=1024*64)
return contents.getvalue() return contents.getvalue()
@ftperrors @ftperrors
...@@ -1141,9 +1138,11 @@ class FTPFS(FS): ...@@ -1141,9 +1138,11 @@ class FTPFS(FS):
@ftperrors @ftperrors
def makedir(self, path, recursive=False, allow_recreate=False): def makedir(self, path, recursive=False, allow_recreate=False):
path = normpath(path)
if path in ('', '/'): if path in ('', '/'):
return return
def checkdir(path): def checkdir(path):
if not self.isdir(path):
self.clear_dircache(dirname(path)) self.clear_dircache(dirname(path))
try: try:
self.ftp.mkd(_encode(path)) self.ftp.mkd(_encode(path))
...@@ -1182,7 +1181,7 @@ class FTPFS(FS): ...@@ -1182,7 +1181,7 @@ class FTPFS(FS):
@ftperrors @ftperrors
def removedir(self, path, recursive=False, force=False): def removedir(self, path, recursive=False, force=False):
path = abspath(normpath(path))
if not self.exists(path): if not self.exists(path):
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
if self.isfile(path): if self.isfile(path):
...@@ -1258,6 +1257,7 @@ class FTPFS(FS): ...@@ -1258,6 +1257,7 @@ class FTPFS(FS):
@ftperrors @ftperrors
def desc(self, path): def desc(self, path):
path = normpath(path)
url = self.getpathurl(path, allow_none=True) url = self.getpathurl(path, allow_none=True)
if url: if url:
return url return url
...@@ -1268,7 +1268,6 @@ class FTPFS(FS): ...@@ -1268,7 +1268,6 @@ class FTPFS(FS):
@ftperrors @ftperrors
def move(self, src, dst, overwrite=False, chunk_size=16384): def move(self, src, dst, overwrite=False, chunk_size=16384):
if not overwrite and self.exists(dst): if not overwrite and self.exists(dst):
raise DestinationExistsError(dst) raise DestinationExistsError(dst)
#self.refresh_dircache(dirname(src), dirname(dst)) #self.refresh_dircache(dirname(src), dirname(dst))
...@@ -1282,7 +1281,6 @@ class FTPFS(FS): ...@@ -1282,7 +1281,6 @@ class FTPFS(FS):
@ftperrors @ftperrors
def copy(self, src, dst, overwrite=False, chunk_size=1024*64): def copy(self, src, dst, overwrite=False, chunk_size=1024*64):
if not self.isfile(src): if not self.isfile(src):
if self.isdir(src): if self.isdir(src):
raise ResourceInvalidError(src, msg="Source is not a file: %(path)s") raise ResourceInvalidError(src, msg="Source is not a file: %(path)s")
...@@ -1290,12 +1288,13 @@ class FTPFS(FS): ...@@ -1290,12 +1288,13 @@ class FTPFS(FS):
if not overwrite and self.exists(dst): if not overwrite and self.exists(dst):
raise DestinationExistsError(dst) raise DestinationExistsError(dst)
dst = normpath(dst)
src_file = None src_file = None
try: try:
src_file = self.open(src, "rb") src_file = self.open(src, "rb")
ftp = self._open_ftp() ftp = self._open_ftp()
ftp.voidcmd('TYPE I') ftp.voidcmd('TYPE I')
ftp.storbinary('STOR %s' % _encode((normpath(dst))), src_file, blocksize=chunk_size) ftp.storbinary('STOR %s' % _encode(normpath(dst)), src_file, blocksize=chunk_size)
finally: finally:
self.refresh_dircache(dirname(dst)) self.refresh_dircache(dirname(dst))
if src_file is not None: if src_file is not None:
......
...@@ -10,7 +10,7 @@ __all__ = ['OpenerError', ...@@ -10,7 +10,7 @@ __all__ = ['OpenerError',
import sys import sys
from fs.osfs import OSFS from fs.osfs import OSFS
from fs.path import pathsplit, basename, join, iswildcard from fs.path import pathsplit, basename, join, iswildcard, normpath
import os import os
import os.path import os.path
import re import re
...@@ -26,13 +26,15 @@ def _expand_syspath(path): ...@@ -26,13 +26,15 @@ def _expand_syspath(path):
if path is None: if path is None:
return path return path
path = os.path.expanduser(os.path.expandvars(path)) path = os.path.expanduser(os.path.expandvars(path))
path = os.path.normpath(os.path.abspath(path)) path = normpath(path)
if sys.platform == "win32": #path = os.path.normpath(os.path.abspath(path))
if not path.startswith("\\\\?\\"):
path = u"\\\\?\\" + root_path #if sys.platform == "win32":
# If it points at the root of a drive, it needs a trailing slash. # if not path.startswith("\\\\?\\"):
if len(path) == 6: # path = u"\\\\?\\" + path
path = path + "\\" # # If it points at the root of a drive, it needs a trailing slash.
# if len(path) == 6:
# path = path + "\\"
return path return path
...@@ -279,7 +281,7 @@ class OSFSOpener(Opener): ...@@ -279,7 +281,7 @@ class OSFSOpener(Opener):
def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir): def get_fs(cls, registry, fs_name, fs_name_params, fs_path, writeable, create_dir):
from fs.osfs import OSFS from fs.osfs import OSFS
path = _expand_syspath(fs_path) path = normpath(fs_path)
if create_dir and not os.path.exists(path): if create_dir and not os.path.exists(path):
from fs.osfs import _os_makedirs from fs.osfs import _os_makedirs
_os_makedirs(path) _os_makedirs(path)
......
...@@ -320,23 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS): ...@@ -320,23 +320,23 @@ class OSFS(OSFSXAttrMixin, OSFSWatchMixin, FS):
def getsize(self, path): def getsize(self, path):
return self._stat(path).st_size return self._stat(path).st_size
@convert_os_errors #@convert_os_errors
def opendir(self, path): #def opendir(self, path):
"""A specialised opendir that returns another OSFS rather than a SubDir # """A specialised opendir that returns another OSFS rather than a SubDir
#
This is more optimal than a SubDir because no path delegation is required. # This is more optimal than a SubDir because no path delegation is required.
#
""" # """
if path in ('', '/'): # if path in ('', '/'):
return self # return self
path = normpath(path) # path = normpath(path)
if not self.exists(path): # if not self.exists(path):
raise ResourceNotFoundError(path) # raise ResourceNotFoundError(path)
sub_path = pathjoin(self.root_path, path) # sub_path = pathjoin(self.root_path, path)
return OSFS(sub_path, # return OSFS(sub_path,
thread_synchronize=self.thread_synchronize, # thread_synchronize=self.thread_synchronize,
encoding=self.encoding, # encoding=self.encoding,
create=False, # create=False,
dir_mode=self.dir_mode) # dir_mode=self.dir_mode)
...@@ -119,9 +119,7 @@ def relpath(path): ...@@ -119,9 +119,7 @@ def relpath(path):
'a/b' 'a/b'
""" """
while path and path[0] == "/": return path.lstrip('/')
path = path[1:]
return path
def pathjoin(*paths): def pathjoin(*paths):
...@@ -148,9 +146,9 @@ def pathjoin(*paths): ...@@ -148,9 +146,9 @@ def pathjoin(*paths):
absolute = True absolute = True
relpaths.append(p) relpaths.append(p)
path = normpath("/".join(relpaths)) path = normpath(u"/".join(relpaths))
if absolute and not path.startswith("/"): if absolute:
path = u"/" + path path = abspath(path)
return path return path
# Allow pathjoin() to be used as fs.path.join() # Allow pathjoin() to be used as fs.path.join()
......
...@@ -453,6 +453,8 @@ class SFTPFS(FS): ...@@ -453,6 +453,8 @@ class SFTPFS(FS):
self.remove(path2) self.remove(path2)
except ResourceInvalidError: except ResourceInvalidError:
self.removedir(path2,force=True) self.removedir(path2,force=True)
if not self.exists(path):
raise ResourceNotFoundError(path)
try: try:
self.client.rmdir(npath) self.client.rmdir(npath)
except IOError, e: except IOError, e:
...@@ -460,6 +462,7 @@ class SFTPFS(FS): ...@@ -460,6 +462,7 @@ class SFTPFS(FS):
if self.isfile(path): if self.isfile(path):
raise ResourceInvalidError(path,msg="Can't use removedir() on a file: %(path)s") raise ResourceInvalidError(path,msg="Can't use removedir() on a file: %(path)s")
raise ResourceNotFoundError(path) raise ResourceNotFoundError(path)
elif self.listdir(path): elif self.listdir(path):
raise DirectoryNotEmptyError(path) raise DirectoryNotEmptyError(path)
raise raise
......
...@@ -697,8 +697,9 @@ class FSTestCases(object): ...@@ -697,8 +697,9 @@ class FSTestCases(object):
def chunk_stream(): def chunk_stream():
"""Generate predictable-but-randomy binary content.""" """Generate predictable-but-randomy binary content."""
r = random.Random(0) r = random.Random(0)
randint = r.randint
for i in xrange(num_chunks): for i in xrange(num_chunks):
c = "".join(chr(r.randint(0,255)) for j in xrange(chunk_size/8)) c = "".join(chr(randint(0,255)) for j in xrange(chunk_size/8))
yield c * 8 yield c * 8
f = self.fs.open("bigfile","wb") f = self.fs.open("bigfile","wb")
try: try:
......
...@@ -14,29 +14,30 @@ import time ...@@ -14,29 +14,30 @@ import time
from fs.tests import FSTestCases, ThreadingTestCases from fs.tests import FSTestCases, ThreadingTestCases
from fs.tempfs import TempFS from fs.tempfs import TempFS
from fs.osfs import OSFS from fs.osfs import OSFS
from fs.memoryfs import MemoryFS
from fs.path import * from fs.path import *
from fs.errors import * from fs.errors import *
from fs import rpcfs from fs import rpcfs
from fs.expose.xmlrpc import RPCFSServer from fs.expose.xmlrpc import RPCFSServer
class TestRPCFS(unittest.TestCase,FSTestCases,ThreadingTestCases): class TestRPCFS(unittest.TestCase, FSTestCases, ThreadingTestCases):
def makeServer(self,fs,addr): def makeServer(self,fs,addr):
return RPCFSServer(fs,addr,logRequests=False) return RPCFSServer(fs,addr,logRequests=False)
def startServer(self): def startServer(self):
port = 8000 port = 3000
self.temp_fs = TempFS() self.temp_fs = TempFS()
self.server = None self.server = None
while not self.server: while not self.server:
try: try:
self.server = self.makeServer(self.temp_fs,("localhost",port)) self.server = self.makeServer(self.temp_fs,("127.0.0.1",port))
except socket.error, e: except socket.error, e:
if e.args[1] == "Address already in use": if e.args[1] == "Address already in use":
port += 1 port += 1
else: else:
raise raise
self.server_addr = ("localhost",port) self.server_addr = ("127.0.0.1",port)
self.serve_more_requests = True self.serve_more_requests = True
self.server_thread = threading.Thread(target=self.runServer) self.server_thread = threading.Thread(target=self.runServer)
self.server_thread.daemon = True self.server_thread.daemon = True
...@@ -76,7 +77,7 @@ class TestRPCFS(unittest.TestCase,FSTestCases,ThreadingTestCases): ...@@ -76,7 +77,7 @@ class TestRPCFS(unittest.TestCase,FSTestCases,ThreadingTestCases):
sock = None sock = None
try: try:
sock = socket.socket(af, socktype, proto) sock = socket.socket(af, socktype, proto)
sock.settimeout(1) sock.settimeout(.1)
sock.connect(sa) sock.connect(sa)
sock.send("\n") sock.send("\n")
except socket.error, e: except socket.error, e:
...@@ -97,6 +98,14 @@ class TestSFTPFS(TestRPCFS): ...@@ -97,6 +98,14 @@ class TestSFTPFS(TestRPCFS):
self.startServer() self.startServer()
self.fs = sftpfs.SFTPFS(self.server_addr, no_auth=True) self.fs = sftpfs.SFTPFS(self.server_addr, no_auth=True)
#def runServer(self):
# self.server.serve_forever()
#
#def tearDown(self):
# self.server.shutdown()
# self.server_thread.join()
# self.temp_fs.close()
def bump(self): def bump(self):
# paramiko doesn't like being bumped, just wait for it to timeout. # paramiko doesn't like being bumped, just wait for it to timeout.
# TODO: do this using a paramiko.Transport() connection # TODO: do this using a paramiko.Transport() connection
......
#!/usr/bin/env python
from fs.tests import FSTestCases, ThreadingTestCases from fs.tests import FSTestCases, ThreadingTestCases
import unittest import unittest
...@@ -25,12 +25,15 @@ class TestFTPFS(unittest.TestCase, FSTestCases, ThreadingTestCases): ...@@ -25,12 +25,15 @@ class TestFTPFS(unittest.TestCase, FSTestCases, ThreadingTestCases):
def setUp(self): def setUp(self):
global ftp_port global ftp_port
#ftp_port += 1 ftp_port += 1
use_port = str(ftp_port) use_port = str(ftp_port)
#ftp_port = 10000 #ftp_port = 10000
self.temp_dir = tempfile.mkdtemp(u"ftpfstests") self.temp_dir = tempfile.mkdtemp(u"ftpfstests")
self.ftp_server = subprocess.Popen([sys.executable, abspath(__file__), self.temp_dir, str(use_port)]) file_path = __file__
if ':' not in file_path:
file_path = abspath(file_path)
self.ftp_server = subprocess.Popen([sys.executable, file_path, self.temp_dir, str(use_port)])
# Need to sleep to allow ftp server to start # Need to sleep to allow ftp server to start
time.sleep(.2) time.sleep(.2)
self.fs = ftpfs.FTPFS('127.0.0.1', 'user', '12345', dircache=True, port=use_port, timeout=5.0) self.fs = ftpfs.FTPFS('127.0.0.1', 'user', '12345', dircache=True, port=use_port, timeout=5.0)
...@@ -40,14 +43,15 @@ class TestFTPFS(unittest.TestCase, FSTestCases, ThreadingTestCases): ...@@ -40,14 +43,15 @@ class TestFTPFS(unittest.TestCase, FSTestCases, ThreadingTestCases):
def tearDown(self): def tearDown(self):
if sys.platform == 'win32': if sys.platform == 'win32':
import win32api import win32api
win32api.TerminateProcess(int(process._handle), -1) os.popen('TASKKILL /PID '+str(self.ftp_server.pid)+' /F')
else: else:
os.system('kill '+str(self.ftp_server.pid)) os.system('kill '+str(self.ftp_server.pid))
shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir)
self.fs.close() self.fs.close()
def check(self, p): def check(self, p):
return os.path.exists(os.path.join(self.temp_dir, relpath(p))) check_path = self.temp_dir.rstrip(os.sep) + os.sep + p
return os.path.exists(check_path.encode('utf-8'))
if __name__ == "__main__": if __name__ == "__main__":
......
...@@ -448,7 +448,7 @@ def print_fs(fs, path='/', max_levels=5, file_out=None, terminal_colors=None, hi ...@@ -448,7 +448,7 @@ def print_fs(fs, path='/', max_levels=5, file_out=None, terminal_colors=None, hi
terminal_colors = True terminal_colors = True
def write(line): def write(line):
file_out.write(line.encode(file_encoding)+'\n') file_out.write(line.encode(file_encoding, 'replace')+'\n')
def wrap_prefix(prefix): def wrap_prefix(prefix):
if not terminal_colors: if not terminal_colors:
......
...@@ -38,7 +38,7 @@ setup(name='fs', ...@@ -38,7 +38,7 @@ setup(name='fs',
packages=['fs','fs.expose','fs.expose.fuse','fs.tests','fs.wrapfs', packages=['fs','fs.expose','fs.expose.fuse','fs.tests','fs.wrapfs',
'fs.osfs','fs.contrib','fs.contrib.bigfs','fs.contrib.davfs', 'fs.osfs','fs.contrib','fs.contrib.bigfs','fs.contrib.davfs',
'fs.expose.dokan', 'fs.commands'], 'fs.expose.dokan', 'fs.commands'],
scripts=['fs/commands/%s' % command for command in COMMANDS], scripts=['fs/commands/%s.py' % command for command in COMMANDS],
classifiers=classifiers, classifiers=classifiers,
) )
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment