Merge lp:~aaron-whitehouse/duplicity/08-unicode into lp:~duplicity-team/duplicity/0.8-series

Proposed by Aaron Whitehouse
Status: Merged
Merged at revision: 1286
Proposed branch: lp:~aaron-whitehouse/duplicity/08-unicode
Merge into: lp:~duplicity-team/duplicity/0.8-series
Diff against target: 5231 lines (+1843/-1584)
26 files modified
bin/duplicity.1 (+5/-5)
debian/control (+2/-0)
duplicity/backend.py (+1/-1)
duplicity/commandline.py (+6/-6)
duplicity/globals.py (+1/-1)
duplicity/globmatch.py (+49/-39)
duplicity/path.py (+13/-0)
duplicity/selection.py (+54/-49)
duplicity/util.py (+34/-3)
requirements.txt (+1/-0)
setup.py (+1/-1)
testing/__init__.py (+6/-4)
testing/functional/__init__.py (+54/-26)
testing/functional/test_badupload.py (+1/-1)
testing/functional/test_cleanup.py (+14/-14)
testing/functional/test_final.py (+41/-41)
testing/functional/test_replicate.py (+10/-10)
testing/functional/test_restart.py (+63/-63)
testing/functional/test_selection.py (+660/-578)
testing/functional/test_verify.py (+20/-20)
testing/unit/test_diffdir.py (+0/-2)
testing/unit/test_globmatch.py (+118/-59)
testing/unit/test_gpg.py (+6/-6)
testing/unit/test_patchdir.py (+0/-1)
testing/unit/test_selection.py (+681/-654)
tox.ini (+2/-0)
To merge this branch: bzr merge lp:~aaron-whitehouse/duplicity/08-unicode
Reviewer Review Type Date Requested Status
duplicity-team Pending
Review via email: mp+334622@code.launchpad.net

Commit message

Many strings have been changed to unicode for better handling of international characters and to make the transition to Python 3 significantly easier, primarily on the 'local' side of duplicity (selection, commandline arguments etc) rather than any backends etc.

Description of the change

Many strings have been changed to unicode for better handling of international characters and to make the transition to Python 3 significantly easier.

In order to merge the changes back into trunk as soon as possible, this branch focuses on just the strings in the 'local' side of duplicity, i.e. those involved in interpreting the selection functions from the commandline arguments or include/exclude lists and reading each file from the local filesystem to compare to these selection functions.

Note:
* This branch introduces Path.uc_name with the filename in unicode, in addition to Path.name with the filename in bytes (i.e. each Path will have a .name and .uc_name). These are both created for each Path object and code throughout duplicity should move to using .uc_name where it needs the unicode name and .name where it needs the bytes name, rather than converting. Valid filenames on the disk in Linux can be invalid unicode, so for Python 2 support it is important that we keep the original bytes .name and use that rather than converting the unicode version. That said, for all internal purposes (e.g. string comparison) we should be using the unicode version. From Python 3.2, it looks as though this has been solved properly and os.fsencode/os.fsencode uses 'surrogateescape' characters (https://www.python.org/dev/peps/pep-0383/ ) to ensure you can always recreate the original bytes filename from the internal unicode representation. As I understand it, that should allow the more standard "decode/encode at the boundaries, use unicode everywhere internally" approach.
* Path.name may be renamed Path.b_name in the future: http://lists.nongnu.org/archive/html/duplicity-talk/2017-11/msg00017.html

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/duplicity.1'
2--- bin/duplicity.1 2017-09-06 14:57:00 +0000
3+++ bin/duplicity.1 2017-12-01 23:01:42 +0000
4@@ -1498,11 +1498,11 @@
5 and
6 .BI --exclude-filelist ,
7 options also introduce file selection conditions. They direct
8-duplicity to read in a file, each line of which is a file
9-specification, and to include or exclude the matching files. Lines
10-are separated by newlines or nulls, depending on whether the
11---null-separator switch was given. Each line in the filelist will be
12-interpreted as a globbing pattern the way
13+duplicity to read in a text file (either ASCII or UTF-8), each line
14+of which is a file specification, and to include or exclude the
15+matching files. Lines are separated by newlines or nulls, depending
16+on whether the --null-separator switch was given. Each line in the
17+filelist will be interpreted as a globbing pattern the way
18 .BI --include
19 and
20 .BI --exclude
21
22=== modified file 'debian/control'
23--- debian/control 2017-10-12 19:42:50 +0000
24+++ debian/control 2017-12-01 23:01:42 +0000
25@@ -11,6 +11,7 @@
26 pylint,
27 python-dev,
28 python-fasteners,
29+ python-future,
30 python-mock,
31 python-pexpect,
32 python-setuptools,
33@@ -28,6 +29,7 @@
34 ${shlibs:Depends},
35 gnupg,
36 python-fasteners,
37+ python-future,
38 python-pexpect,
39 Suggests: ncftp,
40 python-boto,
41
42=== modified file 'duplicity/backend.py'
43--- duplicity/backend.py 2017-11-23 13:02:23 +0000
44+++ duplicity/backend.py 2017-12-01 23:01:42 +0000
45@@ -383,7 +383,7 @@
46 if at_end and fatal:
47 def make_filename(f):
48 if isinstance(f, path.ROPath):
49- return util.escape(f.name)
50+ return util.escape(f.uc_name)
51 else:
52 return util.escape(f)
53 extra = ' '.join([operation] + [make_filename(x) for x in args if x])
54
55=== modified file 'duplicity/commandline.py'
56--- duplicity/commandline.py 2017-09-01 11:46:59 +0000
57+++ duplicity/commandline.py 2017-12-01 23:01:42 +0000
58@@ -30,6 +30,7 @@
59 import re
60 import sys
61 import socket
62+import io
63
64 try:
65 from hashlib import md5
66@@ -251,14 +252,13 @@
67 globals.time_separator = sep
68 old_fn_deprecation(opt)
69
70- def add_selection(o, s, v, p):
71- select_opts.append((s, v))
72+ def add_selection(o, option, additional_arg, p):
73+ select_opts.append((util.fsdecode(option), util.fsdecode(additional_arg)))
74
75- def add_filelist(o, s, v, p):
76- filename = v
77- select_opts.append((s, filename))
78+ def add_filelist(o, s, filename, p):
79+ select_opts.append((util.fsdecode(s), util.fsdecode(filename)))
80 try:
81- select_files.append(open(filename, "r"))
82+ select_files.append(io.open(filename, "rt", encoding="UTF-8"))
83 except IOError:
84 log.FatalError(_("Error opening file %s") % filename,
85 log.ErrorCode.cant_open_filelist)
86
87=== modified file 'duplicity/globals.py'
88--- duplicity/globals.py 2017-11-23 13:02:23 +0000
89+++ duplicity/globals.py 2017-12-01 23:01:42 +0000
90@@ -321,4 +321,4 @@
91 # 'utf-8' or some other sane encoding, but will sometimes fail and return
92 # either 'ascii' or None. Both are bogus, so default to 'utf-8' if it does.
93 fsencoding = sys.getfilesystemencoding()
94-fsencoding = fsencoding if fsencoding not in ['ascii', None] else 'utf-8'
95+fsencoding = fsencoding if fsencoding not in ['ascii', 'ANSI_X3.4-1968', None] else 'utf-8'
96
97=== modified file 'duplicity/globmatch.py'
98--- duplicity/globmatch.py 2017-07-11 14:55:38 +0000
99+++ duplicity/globmatch.py 2017-12-01 23:01:42 +0000
100@@ -19,9 +19,15 @@
101 # You should have received a copy of the GNU General Public License
102 # along with duplicity; if not, write to the Free Software Foundation,
103 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
104+#
105+# All functions in this module only accept unicode. Any byte strings should
106+# be converted to unicode before sending them into this.
107
108 import re
109
110+from builtins import map
111+from builtins import range
112+
113
114 class GlobbingError(Exception):
115 """Something has gone wrong when parsing a glob string"""
116@@ -36,16 +42,16 @@
117 def _glob_get_prefix_regexs(glob_str):
118 """Return list of regexps equivalent to prefixes of glob_str"""
119 # Internal. Used by glob_get_normal_sf.
120- glob_parts = glob_str.split("/")
121- if "" in glob_parts[1:-1]:
122+ glob_parts = glob_str.split(u"/")
123+ if u"" in glob_parts[1:-1]:
124 # "" OK if comes first or last, as in /foo/
125- raise GlobbingError("Consecutive '/'s found in globbing string " +
126+ raise GlobbingError(u"Consecutive '/'s found in globbing string " +
127 glob_str)
128
129- prefixes = ["/".join(glob_parts[:i + 1]) for i in range(len(glob_parts))]
130+ prefixes = [u"/".join(glob_parts[:i + 1]) for i in range(len(glob_parts))]
131 # we must make exception for root "/", only dir to end in slash
132- if prefixes[0] == "":
133- prefixes[0] = "/"
134+ if prefixes[0] == u"":
135+ prefixes[0] = u"/"
136 return list(map(glob_to_regex, prefixes))
137
138
139@@ -62,12 +68,13 @@
140
141 Note: including a folder implicitly includes everything within it.
142 """
143+ assert isinstance(glob_str, unicode)
144 glob_ends_w_slash = False
145
146- if glob_str == "/":
147+ if glob_str == u"/":
148 # If the glob string is '/', it implicitly includes everything
149- glob_str = "/**"
150- elif glob_str[-1] == "/":
151+ glob_str = u"/**"
152+ elif glob_str[-1] == u"/":
153 glob_ends_w_slash = True
154 # Remove trailing / from directory name (unless that is the entire
155 # string)
156@@ -87,39 +94,39 @@
157 # Note that the "/" at the end of the regex means that it will match
158 # if the glob matches a parent folders of path, i.e. including a folder
159 # includes everything within it.
160- glob_comp_re = re_comp("^%s($|/)" % glob_to_regex(glob_str))
161+ glob_comp_re = re_comp(u"^%s($|/)" % glob_to_regex(glob_str))
162
163 if glob_ends_w_slash:
164 # Creates a version of glob_comp_re that does not match folder contents
165 # This can be used later to check that an exact match is actually a
166 # folder, rather than a file.
167- glob_comp_re_exact = re_comp("^%s($)" % glob_to_regex(glob_str))
168+ glob_comp_re_exact = re_comp(u"^%s($)" % glob_to_regex(glob_str))
169
170- if glob_str.find("**") != -1:
171+ if glob_str.find(u"**") != -1:
172 # glob_str has a ** in it
173- glob_str = glob_str[:glob_str.find("**") + 2] # truncate after **
174+ glob_str = glob_str[:glob_str.find(u"**") + 2] # truncate after **
175
176 # Below regex is translates to:
177 # ^ string must be at the beginning of path
178 # the regexs corresponding to the parent directories of glob_str
179 # $ nothing must follow except for the end of the string or newline
180- scan_comp_re = re_comp("^(%s)$" %
181- "|".join(_glob_get_prefix_regexs(glob_str)))
182+ scan_comp_re = re_comp(u"^(%s)$" %
183+ u"|".join(_glob_get_prefix_regexs(glob_str)))
184
185 def test_fn(path):
186- assert not path.name[-1] == "/" or path.name == "/", \
187- "path.name should never end in '/' during normal operation for " \
188- "normal paths (except '/' alone)\n" \
189- "path.name here is " + path.name + " and glob is " + glob_str
190+ assert not path.uc_name[-1] == u"/" or path.uc_name == u"/", \
191+ u"path.name should never end in '/' during normal operation for " \
192+ u"normal paths (except '/' alone)\n" \
193+ u"path.name here is " + path.uc_name + u" and glob is " + glob_str
194
195- if glob_comp_re.match(path.name):
196+ if glob_comp_re.match(path.uc_name):
197 # Path matches glob, or is contained within a matching folder
198 if not glob_ends_w_slash:
199 return include
200 else:
201 # Glob ended with a /, so we need to check any exact match was
202 # a folder
203- if glob_comp_re_exact.match(path.name):
204+ if glob_comp_re_exact.match(path.uc_name):
205 # Not an included file/folder, so must be a folder to match
206 if path.isdir():
207 # Is a directory, so all is well
208@@ -131,7 +138,7 @@
209 # An included file/folder, so normal approach is fine
210 return include
211
212- elif include == 1 and scan_comp_re.match(path.name):
213+ elif include == 1 and scan_comp_re.match(path.uc_name):
214 return 2
215 else:
216 return None
217@@ -151,34 +158,37 @@
218
219 """
220 # Internal. Used by glob_get_normal_sf, glob_get_prefix_res and unit tests.
221+
222+ assert isinstance(pat, unicode)
223+
224 i, n, res = 0, len(pat), ''
225 while i < n:
226 c, s = pat[i], pat[i:i + 2]
227 i = i + 1
228- if s == '**':
229- res = res + '.*'
230+ if s == u'**':
231+ res = res + u'.*'
232 i = i + 1
233- elif c == '*':
234- res = res + '[^/]*'
235- elif c == '?':
236- res = res + '[^/]'
237- elif c == '[':
238+ elif c == u'*':
239+ res = res + u'[^/]*'
240+ elif c == u'?':
241+ res = res + u'[^/]'
242+ elif c == u'[':
243 j = i
244- if j < n and pat[j] in '!^':
245- j = j + 1
246- if j < n and pat[j] == ']':
247- j = j + 1
248- while j < n and pat[j] != ']':
249+ if j < n and pat[j] in u'!^':
250+ j = j + 1
251+ if j < n and pat[j] == u']':
252+ j = j + 1
253+ while j < n and pat[j] != u']':
254 j = j + 1
255 if j >= n:
256- res = res + '\\[' # interpret the [ literally
257+ res = res + u'\\[' # interpret the [ literally
258 else:
259 # Deal with inside of [..]
260- stuff = pat[i:j].replace('\\', '\\\\')
261+ stuff = pat[i:j].replace(u'\\', u'\\\\')
262 i = j + 1
263- if stuff[0] in '!^':
264- stuff = '^' + stuff[1:]
265- res = res + '[' + stuff + ']'
266+ if stuff[0] in u'!^':
267+ stuff = u'^' + stuff[1:]
268+ res = res + u'[' + stuff + u']'
269 else:
270 res = res + re.escape(c)
271 return res
272
273=== modified file 'duplicity/path.py'
274--- duplicity/path.py 2017-07-11 14:55:38 +0000
275+++ duplicity/path.py 2017-12-01 23:01:42 +0000
276@@ -35,6 +35,7 @@
277 import re
278 import gzip
279 import shutil
280+import sys
281
282 from duplicity import tarfile
283 from duplicity import file_naming
284@@ -511,9 +512,21 @@
285 # self.opened should be true if the file has been opened, and
286 # self.fileobj can override returned fileobj
287 self.opened, self.fileobj = None, None
288+ if isinstance(base, unicode):
289+ # For now (Python 2), it is helpful to know that all paths
290+ # are starting with bytes -- see note above util.fsencode definition
291+ base = util.fsencode(base)
292 self.base = base
293+
294+ # Create self.index, which is the path as a tuple
295 self.index = self.rename_index(index)
296+
297 self.name = os.path.join(base, *self.index)
298+
299+ # We converted any unicode base to filesystem encoding, so self.name should
300+ # be in filesystem encoding already and does not need to change
301+ self.uc_name = util.fsdecode(self.name)
302+
303 self.setdata()
304
305 def setdata(self):
306
307=== modified file 'duplicity/selection.py'
308--- duplicity/selection.py 2017-07-11 14:55:38 +0000
309+++ duplicity/selection.py 2017-12-01 23:01:42 +0000
310@@ -90,7 +90,7 @@
311 assert isinstance(path, Path), str(path)
312 self.selection_functions = []
313 self.rootpath = path
314- self.prefix = self.rootpath.name
315+ self.prefix = self.rootpath.uc_name
316
317 def set_iter(self):
318 """Initialize generator, prepare to iterate."""
319@@ -164,10 +164,10 @@
320
321 if not path.type:
322 # base doesn't exist
323- log.Warn(_("Warning: base %s doesn't exist, continuing") %
324- util.ufn(path.name))
325+ log.Warn(_(u"Warning: base %s doesn't exist, continuing") %
326+ path.uc_name)
327 return
328- log.Debug(_("Selecting %s") % util.ufn(path.name))
329+ log.Debug(_(u"Selecting %s") % path.uc_name)
330 yield path
331 if not path.isdir():
332 return
333@@ -185,10 +185,10 @@
334 if val == 0:
335 if delayed_path_stack:
336 for delayed_path in delayed_path_stack:
337- log.Log(_("Selecting %s") % util.ufn(delayed_path.name), 6)
338+ log.Log(_(u"Selecting %s") % delayed_path.uc_name, 6)
339 yield delayed_path
340 del delayed_path_stack[:]
341- log.Debug(_("Selecting %s") % util.ufn(subpath.name))
342+ log.Debug(_(u"Selecting %s") % subpath.uc_name)
343 yield subpath
344 if subpath.isdir():
345 diryield_stack.append(diryield(subpath))
346@@ -199,14 +199,14 @@
347 def Select(self, path):
348 """Run through the selection functions and return dominant val 0/1/2"""
349 # Only used by diryield and tests. Internal.
350- log.Debug("Selection: examining path %s" % util.ufn(path.name))
351+ log.Debug(u"Selection: examining path %s" % path.uc_name)
352 if not self.selection_functions:
353- log.Debug("Selection: + no selection functions found. Including")
354+ log.Debug(u"Selection: + no selection functions found. Including")
355 return 1
356 scan_pending = False
357 for sf in self.selection_functions:
358 result = sf(path)
359- log.Debug("Selection: result: %4s from function: %s" %
360+ log.Debug(u"Selection: result: %4s from function: %s" %
361 (str(result), sf.name))
362 if result is 2:
363 # Selection function says that the path should be scanned for matching files, but keep going
364@@ -224,12 +224,12 @@
365 result = 1
366
367 if result == 0:
368- log.Debug("Selection: - excluding file")
369+ log.Debug(u"Selection: - excluding file")
370 elif result == 1:
371- log.Debug("Selection: + including file")
372+ log.Debug(u"Selection: + including file")
373 else:
374 assert result == 2
375- log.Debug("Selection: ? scanning directory for matches")
376+ log.Debug(u"Selection: ? scanning directory for matches")
377
378 return result
379
380@@ -246,36 +246,41 @@
381 filelists_index = 0
382 try:
383 for opt, arg in argtuples:
384- if opt == "--exclude":
385+ assert isinstance(opt, unicode), u"option " + opt.decode(sys.getfilesystemencoding(), "ignore") + \
386+ u" is not unicode"
387+ assert isinstance(arg, unicode), u"option " + arg.decode(sys.getfilesystemencoding(), "ignore") + \
388+ u" is not unicode"
389+
390+ if opt == u"--exclude":
391 self.add_selection_func(self.glob_get_sf(arg, 0))
392- elif opt == "--exclude-if-present":
393+ elif opt == u"--exclude-if-present":
394 self.add_selection_func(self.present_get_sf(arg, 0))
395- elif opt == "--exclude-device-files":
396+ elif opt == u"--exclude-device-files":
397 self.add_selection_func(self.devfiles_get_sf())
398- elif (opt == "--exclude-filelist") or (opt == "--exclude-globbing-filelist"):
399+ elif (opt == u"--exclude-filelist") or (opt == u"--exclude-globbing-filelist"):
400 # --exclude-globbing-filelist is now deprecated, as all filelists are globbing
401 # but keep this here for the short term for backwards-compatibility
402 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 0, arg):
403 self.add_selection_func(sf)
404 filelists_index += 1
405- elif opt == "--exclude-other-filesystems":
406+ elif opt == u"--exclude-other-filesystems":
407 self.add_selection_func(self.other_filesystems_get_sf(0))
408- elif opt == "--exclude-regexp":
409+ elif opt == u"--exclude-regexp":
410 self.add_selection_func(self.regexp_get_sf(arg, 0))
411- elif opt == "--exclude-older-than":
412+ elif opt == u"--exclude-older-than":
413 self.add_selection_func(self.exclude_older_get_sf(arg))
414- elif opt == "--include":
415+ elif opt == u"--include":
416 self.add_selection_func(self.glob_get_sf(arg, 1))
417- elif (opt == "--include-filelist") or (opt == "--include-globbing-filelist"):
418+ elif (opt == u"--include-filelist") or (opt == u"--include-globbing-filelist"):
419 # --include-globbing-filelist is now deprecated, as all filelists are globbing
420 # but keep this here for the short term for backwards-compatibility
421 for sf in self.filelist_globbing_get_sfs(filelists[filelists_index], 1, arg):
422 self.add_selection_func(sf)
423 filelists_index += 1
424- elif opt == "--include-regexp":
425+ elif opt == u"--include-regexp":
426 self.add_selection_func(self.regexp_get_sf(arg, 1))
427 else:
428- assert 0, "Bad selection option %s" % opt
429+ assert 0, u"Bad selection option %s" % opt
430 except SelectError as e:
431 self.parse_catch_error(e)
432 assert filelists_index == len(filelists)
433@@ -285,16 +290,16 @@
434 """Deal with selection error exc"""
435 # Internal, used by ParseArgs.
436 if isinstance(exc, FilePrefixError):
437- log.FatalError(_("""\
438+ log.FatalError(_(u"""\
439 Fatal Error: The file specification
440 %s
441 cannot match any files in the base directory
442 %s
443 Useful file specifications begin with the base directory or some
444 pattern (such as '**') which matches the base directory.""") %
445- (exc, util.ufn(self.prefix)), log.ErrorCode.file_prefix_error)
446+ (exc, self.prefix), log.ErrorCode.file_prefix_error)
447 elif isinstance(exc, GlobbingError):
448- log.FatalError(_("Fatal Error while processing expression\n"
449+ log.FatalError(_(u"Fatal Error while processing expression\n"
450 "%s") % exc, log.ErrorCode.globbing_error)
451 else:
452 raise # pylint: disable=misplaced-bare-raise
453@@ -304,7 +309,7 @@
454 # Internal. Used by ParseArgs.
455 if (self.selection_functions and
456 not self.selection_functions[-1].exclude):
457- log.FatalError(_("""\
458+ log.FatalError(_(u"""\
459 Last selection expression:
460 %s
461 only specifies that files be included. Because the default is to
462@@ -333,19 +338,19 @@
463 line = line.strip()
464 if not line: # skip blanks
465 return None, include_default
466- if line[0] == "#": # skip full-line comments
467+ if line.startswith(u"#"): # skip full-line comments
468 return None, include_default
469
470 include = include_default
471- if line[:2] == "+ ":
472+ if line.startswith(u"+ "):
473 # Check for "+ " or "- " syntax
474 include = 1
475 line = line[2:]
476- elif line[:2] == "- ":
477+ elif line.startswith(u"- "):
478 include = 0
479 line = line[2:]
480
481- if (line[:1] == "'" and line[-1:] == "'") or (line[:1] == '"' and line[-1:] == '"'):
482+ if (line.startswith(u"'") and line.endswith(u"'")) or (line.startswith(u'"') and line.endswith(u'"')):
483 line = line[1:-1]
484
485 return line, include
486@@ -360,8 +365,8 @@
487
488 """
489 # Internal. Used by ParseArgs.
490- log.Notice(_("Reading globbing filelist %s") % list_name)
491- separator = globals.null_separator and "\0" or "\n"
492+ log.Notice(_(u"Reading globbing filelist %s") % list_name)
493+ separator = globals.null_separator and u"\0" or u"\n"
494 filelist_fp.seek(0)
495 for line in filelist_fp.read().split(separator):
496 line, include = self.filelist_sanitise_line(line, inc_default)
497@@ -383,7 +388,7 @@
498 return None
499
500 sel_func.exclude = not include
501- sel_func.name = "Match other filesystems"
502+ sel_func.name = u"Match other filesystems"
503 return sel_func
504
505 def regexp_get_sf(self, regexp_string, include):
506@@ -393,24 +398,24 @@
507 try:
508 regexp = re.compile(regexp_string)
509 except Exception:
510- log.Warn(_("Error compiling regular expression %s") % regexp_string)
511+ log.Warn(_(u"Error compiling regular expression %s") % regexp_string)
512 raise
513
514 def sel_func(path):
515- if regexp.search(path.name):
516+ if regexp.search(path.uc_name):
517 return include
518 else:
519 return None
520
521 sel_func.exclude = not include
522- sel_func.name = "Regular expression: %s" % regexp_string
523+ sel_func.name = u"Regular expression: %s" % regexp_string
524 return sel_func
525
526 def devfiles_get_sf(self):
527 """Return a selection function to exclude all dev files"""
528 # Internal. Used by ParseArgs.
529 if self.selection_functions:
530- log.Warn(_("Warning: exclude-device-files is not the first "
531+ log.Warn(_(u"Warning: exclude-device-files is not the first "
532 "selector.\nThis may not be what you intended"))
533
534 def sel_func(path):
535@@ -420,21 +425,22 @@
536 return None
537
538 sel_func.exclude = 1
539- sel_func.name = "Exclude device files"
540+ sel_func.name = u"Exclude device files"
541 return sel_func
542
543 def glob_get_sf(self, glob_str, include):
544 """Return selection function given by glob string"""
545 # Internal. Used by ParseArgs, filelist_globbing_get_sfs and unit tests.
546 assert include == 0 or include == 1
547- if glob_str == "**":
548+ assert isinstance(glob_str, unicode)
549+ if glob_str == u"**":
550 sel_func = lambda path: include
551 else:
552 sel_func = self.glob_get_normal_sf(glob_str, include)
553
554 sel_func.exclude = not include
555- sel_func.name = "Command-line %s glob: %s" % \
556- (include and "include" or "exclude", glob_str)
557+ sel_func.name = u"Command-line %s glob: %s" % \
558+ (include and u"include" or u"exclude", glob_str)
559 return sel_func
560
561 def present_get_sf(self, filename, include):
562@@ -453,9 +459,8 @@
563 # functions. Currently this will give an error for any
564 # locked directory within the folder being backed up.
565 log.Warn(_(
566- "Error accessing possibly locked file %s") % util.ufn(
567- path.name),
568- log.WarningCode.cannot_read, util.escape(path.name))
569+ u"Error accessing possibly locked file %s") % path.uc_name,
570+ log.WarningCode.cannot_read, util.escape(path.uc_name))
571 if diffdir.stats:
572 diffdir.stats.Errors += 1
573 elif path.append(filename).exists():
574@@ -470,8 +475,8 @@
575 log.ErrorCode.not_implemented)
576
577 sel_func.exclude = not include
578- sel_func.name = "Command-line %s filename: %s" % \
579- (include and "include-if-present" or "exclude-if-present", filename)
580+ sel_func.name = u"Command-line %s filename: %s" % \
581+ (include and u"include-if-present" or u"exclude-if-present", filename)
582 return sel_func
583
584 def glob_get_normal_sf(self, glob_str, include):
585@@ -489,8 +494,8 @@
586 things similar to this.
587
588 """
589- # Internal. Used by glob_get_sf and unit tests.
590-
591+ assert isinstance(glob_str, unicode), \
592+ u"The glob string " + glob_str.decode(sys.getfilesystemencoding(), "ignore") + u" is not unicode"
593 ignore_case = False
594
595 if glob_str.lower().startswith("ignorecase:"):
596
597=== modified file 'duplicity/util.py'
598--- duplicity/util.py 2017-11-23 13:02:23 +0000
599+++ duplicity/util.py 2017-12-01 23:01:42 +0000
600@@ -34,6 +34,37 @@
601 import duplicity.globals as globals
602 import duplicity.log as log
603
604+try:
605+ # For paths, just use path.name/uname rather than converting with these
606+ from os import fsencode, fsdecode
607+except ImportError:
608+ # Most likely Python version < 3.2, so define our own fsencode/fsdecode.
609+ # These are functions that encode/decode unicode paths to filesystem encoding,
610+ # but the cleverness is that they handle non-unicode characters on Linux
611+ # There is a *partial* backport to Python2 available here:
612+ # https://github.com/pjdelport/backports.os/blob/master/src/backports/os.py
613+ # but if it cannot be trusted for full-circle translation, then we may as well
614+ # just read and store the bytes version of the path as path.name before
615+ # creating the unicode version (for path matching etc) and ensure that in
616+ # real-world usage (as opposed to testing) we create the path objects from a
617+ # bytes string.
618+ # ToDo: Revisit this once we drop Python 2 support/the backport is complete
619+
620+ def fsencode(unicode_filename):
621+ """Convert a unicode filename to a filename encoded in the system encoding"""
622+ # For paths, just use path.name rather than converting with this
623+ # If we are not doing any cleverness with non-unicode filename bytes,
624+ # encoding to system encoding is good enough
625+ return unicode_filename.encode(sys.getfilesystemencoding(), "replace")
626+
627+ def fsdecode(bytes_filename):
628+ """Convert a filename encoded in the system encoding to unicode"""
629+ # For paths, just use path.uname rather than converting with this
630+ # If we are not doing any cleverness with non-unicode filename bytes,
631+ # decoding using system encoding is good enough. Use "ignore" as
632+ # Linux paths can contain non-Unicode characters
633+ return bytes_filename.decode(globals.fsencoding, "ignore")
634+
635
636 def exception_traceback(limit=50):
637 """
638@@ -58,9 +89,9 @@
639
640
641 def ufn(filename):
642- "Convert a (bytes) filename to unicode for printing"
643- assert not isinstance(filename, unicode)
644- return filename.decode(globals.fsencoding, 'replace')
645+ """Convert a (bytes) filename to unicode for printing"""
646+ # Note: path.uc_name is preferable for paths
647+ return filename.decode(globals.fsencoding, "replace")
648
649
650 def uindex(index):
651
652=== modified file 'requirements.txt'
653--- requirements.txt 2017-05-20 15:07:38 +0000
654+++ requirements.txt 2017-12-01 23:01:42 +0000
655@@ -2,6 +2,7 @@
656 coverage
657 dropbox==6.9.0
658 fasteners
659+future
660 paramiko
661 pexpect
662 pycodestyle
663
664=== modified file 'setup.py'
665--- setup.py 2017-07-11 14:55:38 +0000
666+++ setup.py 2017-12-01 23:01:42 +0000
667@@ -196,7 +196,7 @@
668 ext_modules=ext_modules,
669 scripts=['bin/rdiffdir', 'bin/duplicity'],
670 data_files=data_files,
671- install_requires=['fasteners'],
672+ install_requires=['fasteners', 'future'],
673 tests_require=['fasteners', 'mock', 'pexpect'],
674 test_suite='testing',
675 cmdclass={'test': TestCommand,
676
677=== modified file 'testing/__init__.py'
678--- testing/__init__.py 2017-07-11 14:55:38 +0000
679+++ testing/__init__.py 2017-12-01 23:01:42 +0000
680@@ -55,10 +55,12 @@
681
682 class DuplicityTestCase(unittest.TestCase):
683
684- sign_key = '839E6A2856538CCF'
685- sign_passphrase = 'test'
686- encrypt_key1 = '839E6A2856538CCF'
687- encrypt_key2 = '453005CE9B736B2A'
688+ sign_key = u'839E6A2856538CCF'
689+ sign_passphrase = u'test'
690+ # ToDo: remove the below when gpg code (and test_gpg) is converted to unicode
691+ sign_passphrase_bytes = b'test'
692+ encrypt_key1 = u'839E6A2856538CCF'
693+ encrypt_key2 = u'453005CE9B736B2A'
694
695 def setUp(self):
696 super(DuplicityTestCase, self).setUp()
697
698=== modified file 'testing/functional/__init__.py'
699--- testing/functional/__init__.py 2017-07-11 14:55:38 +0000
700+++ testing/functional/__init__.py 2017-12-01 23:01:42 +0000
701@@ -25,10 +25,11 @@
702 import platform
703 import sys
704 import time
705-import unittest
706
707 from duplicity import backend
708+from duplicity import util
709 from .. import DuplicityTestCase
710+from pkg_resources import parse_version
711
712
713 class CmdError(Exception):
714@@ -64,7 +65,7 @@
715 self.unpack_testfiles()
716
717 self.class_args = []
718- self.backend_url = "file://testfiles/output"
719+ self.backend_url = u"file://testfiles/output"
720 self.last_backup = None
721 self.set_environ('PASSPHRASE', self.sign_passphrase)
722 self.set_environ("SIGN_PASSPHRASE", self.sign_passphrase)
723@@ -84,30 +85,57 @@
724 # We run under setsid and take input from /dev/null (below) because
725 # this way we force a failure if duplicity tries to read from the
726 # console unexpectedly (like for gpg password or such).
727- if platform.platform().startswith('Linux'):
728- cmd_list = ['setsid']
729+
730+ # Check all string inputs are unicode -- we will convert to system encoding before running the command
731+ for item in options:
732+ assert not isinstance(item, str), "item " + unicode(item) + " in options is not unicode"
733+
734+ for item in passphrase_input:
735+ assert isinstance(item, unicode), "item " + unicode(item) + " in passphrase_input is not unicode"
736+
737+ if platform.platform().startswith(u'Linux'):
738+ cmd_list = [u'setsid']
739 if self._setsid_w:
740- cmd_list.extend(["-w"])
741+ cmd_list.extend([u"-w"])
742 else:
743 cmd_list = []
744- cmd_list.extend(["duplicity"])
745+ cmd_list.extend([u"duplicity"])
746 cmd_list.extend(options)
747- cmd_list.extend(["-v0"])
748- cmd_list.extend(["--no-print-statistics"])
749- cmd_list.extend(["--allow-source-mismatch"])
750- cmd_list.extend(["--archive-dir=testfiles/cache"])
751+ cmd_list.extend([u"-v0"])
752+ cmd_list.extend([u"--no-print-statistics"])
753+ cmd_list.extend([u"--allow-source-mismatch"])
754+ cmd_list.extend([u"--archive-dir=testfiles/cache"])
755 if current_time:
756- cmd_list.extend(["--current-time", current_time])
757+ cmd_list.extend([u"--current-time", current_time])
758 cmd_list.extend(self.class_args)
759 if fail:
760- cmd_list.extend(["--fail", str(fail)])
761- cmdline = " ".join(map(lambda x: '"%s"' % x, cmd_list))
762+ cmd_list.extend([u"--fail", unicode(fail)])
763+ cmdline = u" ".join(map(lambda x: u'"%s"' % x, cmd_list))
764
765 if not passphrase_input:
766- cmdline += " < /dev/null"
767- child = pexpect.spawn('/bin/sh', ['-c', cmdline], timeout=None)
768+ cmdline += u" < /dev/null"
769+
770+ # The immediately following block is the nicer way to execute pexpect with
771+ # unicode strings, but we need to have the pre-4.0 version for some time yet,
772+ # so for now this is commented out so tests execute the same way on all systems.
773+
774+ # if parse_version(pexpect.__version__) >= parse_version("4.0"):
775+ # # pexpect.spawn only supports unicode from version 4.0
776+ # # there was a separate pexpect.spawnu in 3.x, but it has an error on readline
777+ # child = pexpect.spawn(u'/bin/sh', [u'-c', cmdline], timeout=None, encoding=sys.getfilesystemencoding())
778+ #
779+ # for passphrase in passphrase_input:
780+ # child.expect(u'passphrase.*:')
781+ # child.sendline(passphrase)
782+ # else:
783+
784+ # Manually encode to filesystem encoding and send to spawn as bytes
785+ # ToDo: Remove this once we no longer have to support systems with pexpect < 4.0
786+ child = pexpect.spawn(b'/bin/sh', [b'-c', cmdline.encode(sys.getfilesystemencoding(),
787+ 'replace')], timeout=None)
788+
789 for passphrase in passphrase_input:
790- child.expect('passphrase.*:')
791+ child.expect(b'passphrase.*:')
792 child.sendline(passphrase)
793
794 # if the command fails, we need to clear its output
795@@ -132,7 +160,7 @@
796
797 def backup(self, type, input_dir, options=[], **kwargs):
798 """Run duplicity backup to default directory"""
799- options = [type, input_dir, self.backend_url, "--volsize", "1"] + options
800+ options = [type, input_dir, self.backend_url, u"--volsize", u"1"] + options
801 before_files = self.get_backend_files()
802
803 # If a chain ends with time X and the next full chain begins at time X,
804@@ -149,27 +177,27 @@
805
806 def restore(self, file_to_restore=None, time=None, options=[], **kwargs):
807 assert not os.system("rm -rf testfiles/restore_out")
808- options = [self.backend_url, "testfiles/restore_out"] + options
809+ options = [self.backend_url, u"testfiles/restore_out"] + options
810 if file_to_restore:
811- options.extend(['--file-to-restore', file_to_restore])
812+ options.extend([u'--file-to-restore', file_to_restore])
813 if time:
814- options.extend(['--restore-time', str(time)])
815+ options.extend([u'--restore-time', unicode(time)])
816 self.run_duplicity(options=options, **kwargs)
817
818 def verify(self, dirname, file_to_verify=None, time=None, options=[],
819 **kwargs):
820- options = ["verify", self.backend_url, dirname] + options
821+ options = [u"verify", self.backend_url, dirname] + options
822 if file_to_verify:
823- options.extend(['--file-to-restore', file_to_verify])
824+ options.extend([u'--file-to-restore', file_to_verify])
825 if time:
826- options.extend(['--restore-time', str(time)])
827+ options.extend([u'--restore-time', unicode(time)])
828 self.run_duplicity(options=options, **kwargs)
829
830 def cleanup(self, options=[]):
831 """
832 Run duplicity cleanup to default directory
833 """
834- options = ["cleanup", self.backend_url, "--force"] + options
835+ options = [u"cleanup", self.backend_url, u"--force"] + options
836 self.run_duplicity(options=options)
837
838 def get_backend_files(self):
839@@ -183,6 +211,6 @@
840 Makes a number of large files in testfiles/largefiles that each are
841 the specified number of megabytes.
842 """
843- assert not os.system("mkdir testfiles/largefiles")
844+ assert not os.system(u"mkdir testfiles/largefiles")
845 for n in range(count):
846- assert not os.system("dd if=/dev/urandom of=testfiles/largefiles/file%d bs=1024 count=%d > /dev/null 2>&1" % (n + 1, size * 1024))
847+ assert not os.system(u"dd if=/dev/urandom of=testfiles/largefiles/file%d bs=1024 count=%d > /dev/null 2>&1" % (n + 1, size * 1024))
848
849=== modified file 'testing/functional/test_badupload.py'
850--- testing/functional/test_badupload.py 2014-12-27 15:16:06 +0000
851+++ testing/functional/test_badupload.py 2017-12-01 23:01:42 +0000
852@@ -34,7 +34,7 @@
853 Test basic lost file
854 """
855 try:
856- self.backup("full", "testfiles/dir1", options=["--skip-volume=1"])
857+ self.backup(u"full", u"testfiles/dir1", options=[u"--skip-volume=1"])
858 self.fail()
859 except CmdError as e:
860 self.assertEqual(e.exit_status, 44, str(e))
861
862=== modified file 'testing/functional/test_cleanup.py'
863--- testing/functional/test_cleanup.py 2014-04-20 05:58:47 +0000
864+++ testing/functional/test_cleanup.py 2017-12-01 23:01:42 +0000
865@@ -35,27 +35,27 @@
866 after a failed backup.
867 """
868 self.make_largefiles()
869- good_files = self.backup("full", "testfiles/largefiles")
870- good_files |= self.backup("inc", "testfiles/largefiles")
871- good_files |= self.backup("inc", "testfiles/largefiles")
872- self.backup("full", "testfiles/largefiles", fail=1)
873+ good_files = self.backup(u"full", u"testfiles/largefiles")
874+ good_files |= self.backup(u"inc", u"testfiles/largefiles")
875+ good_files |= self.backup(u"inc", u"testfiles/largefiles")
876+ self.backup(u"full", u"testfiles/largefiles", fail=1)
877 bad_files = self.get_backend_files()
878 bad_files -= good_files
879 self.assertNotEqual(bad_files, set())
880 # the cleanup should go OK
881- self.run_duplicity(options=["cleanup", self.backend_url, "--force"])
882+ self.run_duplicity(options=[u"cleanup", self.backend_url, u"--force"])
883 leftovers = self.get_backend_files()
884 self.assertEqual(good_files, leftovers)
885- self.backup("inc", "testfiles/largefiles")
886- self.verify("testfiles/largefiles")
887+ self.backup(u"inc", u"testfiles/largefiles")
888+ self.verify(u"testfiles/largefiles")
889
890 def test_remove_all_but_n(self):
891 """
892 Test that remove-all-but-n works in the simple case.
893 """
894- full1_files = self.backup("full", "testfiles/empty_dir")
895- full2_files = self.backup("full", "testfiles/empty_dir")
896- self.run_duplicity(options=["remove-all-but-n", "1", self.backend_url, "--force"])
897+ full1_files = self.backup(u"full", u"testfiles/empty_dir")
898+ full2_files = self.backup(u"full", u"testfiles/empty_dir")
899+ self.run_duplicity(options=[u"remove-all-but-n", u"1", self.backend_url, u"--force"])
900 leftovers = self.get_backend_files()
901 self.assertEqual(full2_files, leftovers)
902
903@@ -63,10 +63,10 @@
904 """
905 Test that remove-all-inc-of-but-n-full works in the simple case.
906 """
907- full1_files = self.backup("full", "testfiles/empty_dir")
908- inc1_files = self.backup("inc", "testfiles/empty_dir")
909- full2_files = self.backup("full", "testfiles/empty_dir")
910- self.run_duplicity(options=["remove-all-inc-of-but-n-full", "1", self.backend_url, "--force"])
911+ full1_files = self.backup(u"full", u"testfiles/empty_dir")
912+ inc1_files = self.backup(u"inc", u"testfiles/empty_dir")
913+ full2_files = self.backup(u"full", u"testfiles/empty_dir")
914+ self.run_duplicity(options=[u"remove-all-inc-of-but-n-full", u"1", self.backend_url, u"--force"])
915 leftovers = self.get_backend_files()
916 self.assertEqual(full1_files | full2_files, leftovers)
917
918
919=== modified file 'testing/functional/test_final.py'
920--- testing/functional/test_final.py 2017-04-22 19:30:28 +0000
921+++ testing/functional/test_final.py 2017-12-01 23:01:42 +0000
922@@ -36,11 +36,11 @@
923
924 # Back up directories to local backend
925 current_time = 100000
926- self.backup("full", dirlist[0], current_time=current_time,
927+ self.backup(u"full", dirlist[0], current_time=current_time,
928 options=backup_options)
929 for new_dir in dirlist[1:]:
930 current_time += 100000
931- self.backup("inc", new_dir, current_time=current_time,
932+ self.backup(u"inc", new_dir, current_time=current_time,
933 options=backup_options)
934
935 # Restore each and compare them
936@@ -48,7 +48,7 @@
937 dirname = dirlist[i]
938 current_time = 100000 * (i + 1)
939 self.restore(time=current_time, options=restore_options)
940- self.check_same(dirname, "testfiles/restore_out")
941+ self.check_same(dirname, u"testfiles/restore_out")
942 self.verify(dirname,
943 time=current_time, options=restore_options)
944
945@@ -59,57 +59,57 @@
946
947 def test_basic_cycle(self, backup_options=[], restore_options=[]):
948 """Run backup/restore test on basic directories"""
949- self.runtest(["testfiles/dir1",
950- "testfiles/dir2",
951- "testfiles/dir3"],
952+ self.runtest([u"testfiles/dir1",
953+ u"testfiles/dir2",
954+ u"testfiles/dir3"],
955 backup_options=backup_options,
956 restore_options=restore_options)
957
958 # Test restoring various sub files
959- for filename, time, dir in [('symbolic_link', 99999, 'dir1'),
960- ('directory_to_file', 100100, 'dir1'),
961- ('directory_to_file', 200100, 'dir2'),
962- ('largefile', 300000, 'dir3')]:
963+ for filename, time, dir in [(u'symbolic_link', 99999, u'dir1'),
964+ (u'directory_to_file', 100100, u'dir1'),
965+ (u'directory_to_file', 200100, u'dir2'),
966+ (u'largefile', 300000, u'dir3')]:
967 self.restore(filename, time, options=restore_options)
968- self.check_same('testfiles/%s/%s' % (dir, filename),
969- 'testfiles/restore_out')
970- self.verify('testfiles/%s/%s' % (dir, filename),
971+ self.check_same(u'testfiles/%s/%s' % (dir, filename),
972+ u'testfiles/restore_out')
973+ self.verify(u'testfiles/%s/%s' % (dir, filename),
974 file_to_verify=filename, time=time,
975 options=restore_options)
976
977 def test_asym_cycle(self):
978 """Like test_basic_cycle but use asymmetric encryption and signing"""
979- backup_options = ["--encrypt-key", self.encrypt_key1,
980- "--sign-key", self.sign_key]
981- restore_options = ["--encrypt-key", self.encrypt_key1,
982- "--sign-key", self.sign_key]
983+ backup_options = [u"--encrypt-key", self.encrypt_key1,
984+ u"--sign-key", self.sign_key]
985+ restore_options = [u"--encrypt-key", self.encrypt_key1,
986+ u"--sign-key", self.sign_key]
987 self.test_basic_cycle(backup_options=backup_options,
988 restore_options=restore_options)
989
990 def test_asym_with_hidden_recipient_cycle(self):
991 """Like test_basic_cycle but use asymmetric encryption (hiding key id) and signing"""
992- backup_options = ["--hidden-encrypt-key", self.encrypt_key1,
993- "--sign-key", self.sign_key]
994- restore_options = ["--hidden-encrypt-key", self.encrypt_key1,
995- "--sign-key", self.sign_key]
996+ backup_options = [u"--hidden-encrypt-key", self.encrypt_key1,
997+ u"--sign-key", self.sign_key]
998+ restore_options = [u"--hidden-encrypt-key", self.encrypt_key1,
999+ u"--sign-key", self.sign_key]
1000 self.test_basic_cycle(backup_options=backup_options,
1001 restore_options=restore_options)
1002
1003 def test_single_regfile(self):
1004 """Test backing and restoring up a single regular file"""
1005- self.runtest(["testfiles/various_file_types/regular_file"])
1006+ self.runtest([u"testfiles/various_file_types/regular_file"])
1007
1008 def test_empty_backup(self):
1009 """Make sure backup works when no files change"""
1010- self.backup("full", "testfiles/empty_dir")
1011- self.backup("inc", "testfiles/empty_dir")
1012+ self.backup(u"full", u"testfiles/empty_dir")
1013+ self.backup(u"inc", u"testfiles/empty_dir")
1014
1015 def test_long_filenames(self):
1016 """Test backing up a directory with long filenames in it"""
1017 # Note that some versions of ecryptfs (at least through Ubuntu 11.10)
1018 # have a bug where they treat the max path segment length as 143
1019 # instead of 255. So make sure that these segments don't break that.
1020- lf_dir = path.Path("testfiles/long_filenames")
1021+ lf_dir = path.Path(u"testfiles/long_filenames")
1022 if lf_dir.exists():
1023 lf_dir.deltree()
1024 lf_dir.mkdir()
1025@@ -130,36 +130,36 @@
1026 fp.write("hello" * 1000)
1027 assert not fp.close()
1028
1029- self.runtest(["testfiles/empty_dir", lf_dir.name,
1030- "testfiles/empty_dir", lf_dir.name])
1031+ self.runtest([u"testfiles/empty_dir", lf_dir.uc_name,
1032+ u"testfiles/empty_dir", lf_dir.uc_name])
1033
1034 def test_empty_restore(self):
1035 """Make sure error raised when restore doesn't match anything"""
1036- self.backup("full", "testfiles/dir1")
1037- self.assertRaises(CmdError, self.restore, "this_file_does_not_exist")
1038- self.backup("inc", "testfiles/empty_dir")
1039- self.assertRaises(CmdError, self.restore, "this_file_does_not_exist")
1040+ self.backup(u"full", u"testfiles/dir1")
1041+ self.assertRaises(CmdError, self.restore, u"this_file_does_not_exist")
1042+ self.backup(u"inc", u"testfiles/empty_dir")
1043+ self.assertRaises(CmdError, self.restore, u"this_file_does_not_exist")
1044
1045 def test_remove_older_than(self):
1046 """Test removing old backup chains"""
1047- first_chain = self.backup("full", "testfiles/dir1", current_time=10000)
1048- first_chain |= self.backup("inc", "testfiles/dir2", current_time=20000)
1049- second_chain = self.backup("full", "testfiles/dir1", current_time=30000)
1050- second_chain |= self.backup("inc", "testfiles/dir3", current_time=40000)
1051+ first_chain = self.backup(u"full", u"testfiles/dir1", current_time=10000)
1052+ first_chain |= self.backup(u"inc", u"testfiles/dir2", current_time=20000)
1053+ second_chain = self.backup(u"full", u"testfiles/dir1", current_time=30000)
1054+ second_chain |= self.backup(u"inc", u"testfiles/dir3", current_time=40000)
1055
1056 self.assertEqual(self.get_backend_files(), first_chain | second_chain)
1057
1058- self.run_duplicity(options=["remove-older-than", "35000", "--force", self.backend_url])
1059+ self.run_duplicity(options=[u"remove-older-than", u"35000", u"--force", self.backend_url])
1060 self.assertEqual(self.get_backend_files(), second_chain)
1061
1062 # Now check to make sure we can't delete only chain
1063- self.run_duplicity(options=["remove-older-than", "50000", "--force", self.backend_url])
1064+ self.run_duplicity(options=[u"remove-older-than", u"50000", u"--force", self.backend_url])
1065 self.assertEqual(self.get_backend_files(), second_chain)
1066
1067 def test_piped_password(self):
1068 """Make sure that prompting for a password works"""
1069- self.set_environ("PASSPHRASE", None)
1070- self.backup("full", "testfiles/empty_dir",
1071+ self.set_environ(u"PASSPHRASE", None)
1072+ self.backup(u"full", u"testfiles/empty_dir",
1073 passphrase_input=[self.sign_passphrase, self.sign_passphrase])
1074 self.restore(passphrase_input=[self.sign_passphrase])
1075
1076@@ -168,14 +168,14 @@
1077
1078 def setUp(self):
1079 super(OldFilenamesFinalTest, self).setUp()
1080- self.class_args.extend(["--old-filenames"])
1081+ self.class_args.extend([u"--old-filenames"])
1082
1083
1084 class ShortFilenamesFinalTest(FinalTest):
1085
1086 def setUp(self):
1087 super(ShortFilenamesFinalTest, self).setUp()
1088- self.class_args.extend(["--short-filenames"])
1089+ self.class_args.extend([u"--short-filenames"])
1090
1091 if __name__ == "__main__":
1092 unittest.main()
1093
1094=== modified file 'testing/functional/test_replicate.py'
1095--- testing/functional/test_replicate.py 2017-06-20 15:20:35 +0000
1096+++ testing/functional/test_replicate.py 2017-12-01 23:01:42 +0000
1097@@ -34,17 +34,17 @@
1098 def runtest(self, dirlist, backup_options=[], replicate_options=[], restore_options=[]):
1099 # Back up directories to local backend
1100 current_time = 100000
1101- self.backup("full", dirlist[0], current_time=current_time,
1102+ self.backup(u"full", dirlist[0], current_time=current_time,
1103 options=backup_options)
1104 for new_dir in dirlist[1:]:
1105 current_time += 100000
1106- self.backup("inc", new_dir, current_time=current_time,
1107+ self.backup(u"inc", new_dir, current_time=current_time,
1108 options=backup_options)
1109
1110 # Replicate to other backend
1111 source_url = self.backend_url
1112- target_url = "file://testfiles/replicate_out"
1113- self.run_duplicity(options=["replicate"] +
1114+ target_url = u"file://testfiles/replicate_out"
1115+ self.run_duplicity(options=[u"replicate"] +
1116 replicate_options + [source_url, target_url])
1117
1118 self.backend_url = target_url
1119@@ -54,7 +54,7 @@
1120 dirname = dirlist[i]
1121 current_time = 100000 * (i + 1)
1122 self.restore(time=current_time, options=restore_options)
1123- self.check_same(dirname, "testfiles/restore_out")
1124+ self.check_same(dirname, u"testfiles/restore_out")
1125 self.verify(dirname,
1126 time=current_time, options=restore_options)
1127
1128@@ -65,15 +65,15 @@
1129
1130 def test_replicate(self):
1131 """Test replication"""
1132- self.runtest(["testfiles/dir1", "testfiles/dir2"])
1133+ self.runtest([u"testfiles/dir1", u"testfiles/dir2"])
1134
1135 def test_replicate_noencryption(self):
1136 """Test replication with decryption"""
1137- self.runtest(["testfiles/dir1", "testfiles/dir2"],
1138- replicate_options=["--no-encryption"])
1139+ self.runtest([u"testfiles/dir1", u"testfiles/dir2"],
1140+ replicate_options=[u"--no-encryption"])
1141
1142 def test_replicate_asym(self):
1143 """Test replication with reencryption"""
1144- asym_options = ["--encrypt-key", self.encrypt_key1]
1145- self.runtest(["testfiles/dir1", "testfiles/dir2"],
1146+ asym_options = [u"--encrypt-key", self.encrypt_key1]
1147+ self.runtest([u"testfiles/dir1", u"testfiles/dir2"],
1148 replicate_options=asym_options, restore_options=asym_options)
1149
1150=== modified file 'testing/functional/test_restart.py'
1151--- testing/functional/test_restart.py 2017-07-11 14:55:38 +0000
1152+++ testing/functional/test_restart.py 2017-12-01 23:01:42 +0000
1153@@ -37,20 +37,20 @@
1154 Test basic Checkpoint/Restart
1155 """
1156 self.make_largefiles()
1157- self.backup("full", "testfiles/largefiles", fail=1)
1158- self.backup("full", "testfiles/largefiles")
1159- self.verify("testfiles/largefiles")
1160+ self.backup(u"full", u"testfiles/largefiles", fail=1)
1161+ self.backup(u"full", u"testfiles/largefiles")
1162+ self.verify(u"testfiles/largefiles")
1163
1164 def test_multiple_checkpoint_restart(self):
1165 """
1166 Test multiple Checkpoint/Restart
1167 """
1168 self.make_largefiles()
1169- self.backup("full", "testfiles/largefiles", fail=1)
1170- self.backup("full", "testfiles/largefiles", fail=2)
1171- self.backup("full", "testfiles/largefiles", fail=3)
1172- self.backup("full", "testfiles/largefiles")
1173- self.verify("testfiles/largefiles")
1174+ self.backup(u"full", u"testfiles/largefiles", fail=1)
1175+ self.backup(u"full", u"testfiles/largefiles", fail=2)
1176+ self.backup(u"full", u"testfiles/largefiles", fail=3)
1177+ self.backup(u"full", u"testfiles/largefiles")
1178+ self.verify(u"testfiles/largefiles")
1179
1180 def test_first_volume_failure(self):
1181 """
1182@@ -58,10 +58,10 @@
1183 Caused when duplicity fails before the first transfer.
1184 """
1185 self.make_largefiles()
1186- self.backup("full", "testfiles/largefiles", fail=1)
1187- assert not os.system("rm testfiles/output/duplicity-full*difftar*")
1188- self.backup("full", "testfiles/largefiles")
1189- self.verify("testfiles/largefiles")
1190+ self.backup(u"full", u"testfiles/largefiles", fail=1)
1191+ assert not os.system(u"rm testfiles/output/duplicity-full*difftar*")
1192+ self.backup(u"full", u"testfiles/largefiles")
1193+ self.verify(u"testfiles/largefiles")
1194
1195 def test_multi_volume_failure(self):
1196 """
1197@@ -70,10 +70,10 @@
1198 fails the last queued transfer(s).
1199 """
1200 self.make_largefiles()
1201- self.backup("full", "testfiles/largefiles", fail=3)
1202- assert not os.system("rm testfiles/output/duplicity-full*vol[23].difftar*")
1203- self.backup("full", "testfiles/largefiles")
1204- self.verify("testfiles/largefiles")
1205+ self.backup(u"full", u"testfiles/largefiles", fail=3)
1206+ assert not os.system(u"rm testfiles/output/duplicity-full*vol[23].difftar*")
1207+ self.backup(u"full", u"testfiles/largefiles")
1208+ self.verify(u"testfiles/largefiles")
1209
1210 def test_restart_sign_and_encrypt(self):
1211 """
1212@@ -81,10 +81,10 @@
1213 https://bugs.launchpad.net/duplicity/+bug/946988
1214 """
1215 self.make_largefiles()
1216- enc_opts = ["--sign-key", self.sign_key, "--encrypt-key", self.sign_key]
1217- self.backup("full", "testfiles/largefiles", options=enc_opts, fail=2)
1218- self.backup("full", "testfiles/largefiles", options=enc_opts)
1219- self.verify("testfiles/largefiles")
1220+ enc_opts = [u"--sign-key", self.sign_key, u"--encrypt-key", self.sign_key]
1221+ self.backup(u"full", u"testfiles/largefiles", options=enc_opts, fail=2)
1222+ self.backup(u"full", u"testfiles/largefiles", options=enc_opts)
1223+ self.verify(u"testfiles/largefiles")
1224
1225 def test_restart_sign_and_hidden_encrypt(self):
1226 """
1227@@ -92,10 +92,10 @@
1228 https://bugs.launchpad.net/duplicity/+bug/946988
1229 """
1230 self.make_largefiles()
1231- enc_opts = ["--sign-key", self.sign_key, "--hidden-encrypt-key", self.sign_key]
1232- self.backup("full", "testfiles/largefiles", options=enc_opts, fail=2)
1233- self.backup("full", "testfiles/largefiles", options=enc_opts)
1234- self.verify("testfiles/largefiles")
1235+ enc_opts = [u"--sign-key", self.sign_key, u"--hidden-encrypt-key", self.sign_key]
1236+ self.backup(u"full", u"testfiles/largefiles", options=enc_opts, fail=2)
1237+ self.backup(u"full", u"testfiles/largefiles", options=enc_opts)
1238+ self.verify(u"testfiles/largefiles")
1239
1240 def test_last_file_missing_in_middle(self):
1241 """
1242@@ -104,12 +104,12 @@
1243 the file in the middle of the backup, with files following.
1244 """
1245 self.make_largefiles()
1246- self.backup("full", "testfiles/largefiles", fail=3)
1247- assert not os.system("rm testfiles/largefiles/file2")
1248- self.backup("full", "testfiles/largefiles")
1249+ self.backup(u"full", u"testfiles/largefiles", fail=3)
1250+ assert not os.system(u"rm testfiles/largefiles/file2")
1251+ self.backup(u"full", u"testfiles/largefiles")
1252 # TODO: we can't verify but we need to to check for other errors that might show up
1253 # there should be 2 differences found, one missing file, one mtime change
1254- # self.verify("testfiles/largefiles")
1255+ # self.verify(u"testfiles/largefiles")
1256
1257 def test_last_file_missing_at_end(self):
1258 """
1259@@ -118,22 +118,22 @@
1260 the file at the end of the backup, with no files following.
1261 """
1262 self.make_largefiles()
1263- self.backup("full", "testfiles/largefiles", fail=6)
1264- assert not os.system("rm testfiles/largefiles/file3")
1265- self.backup("full", "testfiles/largefiles")
1266+ self.backup(u"full", u"testfiles/largefiles", fail=6)
1267+ assert not os.system(u"rm testfiles/largefiles/file3")
1268+ self.backup(u"full", u"testfiles/largefiles")
1269 # TODO: we can't verify but we need to to check for other errors that might show up
1270 # there should be 2 differences found, one missing file, one mtime change
1271- # self.verify("testfiles/largefiles")
1272+ # self.verify(u"testfiles/largefiles")
1273
1274 def test_restart_incremental(self):
1275 """
1276 Test restarting an incremental backup
1277 """
1278 self.make_largefiles()
1279- self.backup("full", "testfiles/dir1")
1280- self.backup("inc", "testfiles/largefiles", fail=2)
1281- self.backup("inc", "testfiles/largefiles")
1282- self.verify("testfiles/largefiles")
1283+ self.backup(u"full", u"testfiles/dir1")
1284+ self.backup(u"inc", u"testfiles/largefiles", fail=2)
1285+ self.backup(u"inc", u"testfiles/largefiles")
1286+ self.verify(u"testfiles/largefiles")
1287
1288 def make_fake_second_volume(self, name):
1289 """
1290@@ -175,16 +175,16 @@
1291 If we restart right after a volume that ended with a small
1292 (one-block) file, make sure we restart in the right place.
1293 """
1294- source = 'testfiles/largefiles'
1295+ source = u'testfiles/largefiles'
1296 assert not os.system("mkdir -p %s" % source)
1297 assert not os.system("echo hello > %s/file1" % source)
1298- self.backup("full", source, options=["--name=backup1"])
1299+ self.backup(u"full", source, options=[u"--name=backup1"])
1300 # Fake an interruption
1301- self.make_fake_second_volume("backup1")
1302+ self.make_fake_second_volume(u"backup1")
1303 # Add new file
1304 assert not os.system("cp %s/file1 %s/newfile" % (source, source))
1305 # 'restart' the backup
1306- self.backup("full", source, options=["--name=backup1"])
1307+ self.backup(u"full", source, options=[u"--name=backup1"])
1308 # Confirm we actually resumed the previous backup
1309 self.assertEqual(len(os.listdir("testfiles/output")), 4)
1310 # Now make sure everything is byte-for-byte the same once restored
1311@@ -196,15 +196,15 @@
1312 If we restart right after a volume that ended with a large
1313 (multi-block) file, make sure we restart in the right place.
1314 """
1315- source = 'testfiles/largefiles'
1316+ source = u'testfiles/largefiles'
1317 self.make_largefiles(count=1, size=1)
1318- self.backup("full", source, options=["--volsize=5", "--name=backup1"])
1319+ self.backup(u"full", source, options=[u"--volsize=5", u"--name=backup1"])
1320 # Fake an interruption
1321- self.make_fake_second_volume("backup1")
1322+ self.make_fake_second_volume(u"backup1")
1323 # Add new file
1324 assert not os.system("cp %s/file1 %s/newfile" % (source, source))
1325 # 'restart' the backup
1326- self.backup("full", source, options=["--volsize=5", "--name=backup1"])
1327+ self.backup(u"full", source, options=[u"--volsize=5", u"--name=backup1"])
1328 # Confirm we actually resumed the previous backup
1329 self.assertEqual(len(os.listdir("testfiles/output")), 4)
1330 # Now make sure everything is byte-for-byte the same once restored
1331@@ -216,13 +216,13 @@
1332 If we restart right after a volume that ended inside of a large
1333 (multi-block) file, make sure we restart in the right place.
1334 """
1335- source = 'testfiles/largefiles'
1336+ source = u'testfiles/largefiles'
1337 self.make_largefiles(count=1, size=3)
1338- self.backup("full", source, options=["--name=backup1"])
1339+ self.backup(u"full", source, options=[u"--name=backup1"])
1340 # Fake an interruption
1341- self.make_fake_second_volume("backup1")
1342+ self.make_fake_second_volume(u"backup1")
1343 # 'restart' the backup
1344- self.backup("full", source, options=["--name=backup1"])
1345+ self.backup(u"full", source, options=[u"--name=backup1"])
1346 # Now make sure everything is byte-for-byte the same once restored
1347 self.restore()
1348 assert not os.system("diff -r %s testfiles/restore_out" % source)
1349@@ -234,16 +234,16 @@
1350 (Expected result is to ignore new, ealier files, but pick up later
1351 ones.)
1352 """
1353- source = 'testfiles/largefiles'
1354+ source = u'testfiles/largefiles'
1355 self.make_largefiles(count=1, size=1)
1356- self.backup("full", source, options=["--name=backup1"])
1357+ self.backup(u"full", source, options=[u"--name=backup1"])
1358 # Fake an interruption
1359- self.make_fake_second_volume("backup1")
1360+ self.make_fake_second_volume(u"backup1")
1361 # Add new files, earlier and later in filename sort order
1362 assert not os.system("echo hello > %s/a" % source)
1363 assert not os.system("echo hello > %s/z" % source)
1364 # 'restart' the backup
1365- self.backup("full", source, options=["--name=backup1"])
1366+ self.backup(u"full", source, options=[u"--name=backup1"])
1367 # Now make sure everything is the same once restored, except 'a'
1368 self.restore()
1369 assert not os.system("test ! -e testfiles/restore_out/a")
1370@@ -258,15 +258,15 @@
1371 if the source data changes to be small enough to not create a vol3 on
1372 restart.
1373 """
1374- source = 'testfiles/largefiles'
1375+ source = u'testfiles/largefiles'
1376 self.make_largefiles(count=5, size=1)
1377- self.backup("full", source, fail=3)
1378+ self.backup(u"full", source, fail=3)
1379 # now delete the last volume on remote end and some source files
1380 assert not os.system("rm testfiles/output/duplicity-full*vol3.difftar*")
1381 assert not os.system("rm %s/file[2345]" % source)
1382 assert not os.system("echo hello > %s/z" % source)
1383 # finish backup
1384- self.backup("full", source)
1385+ self.backup(u"full", source)
1386 # and verify we can restore
1387 self.restore()
1388
1389@@ -277,14 +277,14 @@
1390 possible that the first chunk of the next file will be skipped unless
1391 we're careful.
1392 """
1393- source = 'testfiles/largefiles'
1394+ source = u'testfiles/largefiles'
1395 self.make_largefiles(count=1)
1396- self.backup("full", source, fail=2)
1397+ self.backup(u"full", source, fail=2)
1398 # now remove starting source data and make sure we add something after
1399 assert not os.system("rm %s/*" % source)
1400 assert not os.system("echo hello > %s/z" % source)
1401 # finish backup
1402- self.backup("full", source)
1403+ self.backup(u"full", source)
1404 # and verify we can restore
1405 self.restore()
1406 assert not os.system("diff %s/z testfiles/restore_out/z" % source)
1407@@ -295,7 +295,7 @@
1408
1409 def setUp(self):
1410 super(RestartTestWithoutEncryption, self).setUp()
1411- self.class_args.extend(["--no-encryption"])
1412+ self.class_args.extend([u"--no-encryption"])
1413
1414 def test_no_write_double_snapshot(self):
1415 """
1416@@ -305,8 +305,8 @@
1417 https://launchpad.net/bugs/929067
1418 """
1419 self.make_largefiles()
1420- self.backup("full", "testfiles/largefiles", fail=2)
1421- self.backup("full", "testfiles/largefiles")
1422+ self.backup(u"full", u"testfiles/largefiles", fail=2)
1423+ self.backup(u"full", u"testfiles/largefiles")
1424 # Now check sigtar
1425 sigtars = glob.glob("testfiles/output/duplicity-full*.sigtar.gz")
1426 self.assertEqual(1, len(sigtars))
1427@@ -333,7 +333,7 @@
1428 raise Exception("Platform %s not supported by tar/gtar." % platform.platform())
1429
1430 # Intial normal backup
1431- self.backup("full", "testfiles/blocktartest")
1432+ self.backup(u"full", u"testfiles/blocktartest")
1433 # Create an exact clone of the snapshot folder in the sigtar already.
1434 # Permissions and mtime must match.
1435 os.mkdir("testfiles/snapshot", 0o755)
1436@@ -353,7 +353,7 @@
1437 self.assertEqual(0, os.system("rm -r testfiles/cache"))
1438 # Try a follow on incremental (which in buggy versions, would create
1439 # a deleted entry for the base dir)
1440- self.backup("inc", "testfiles/blocktartest")
1441+ self.backup(u"inc", u"testfiles/blocktartest")
1442 self.assertEqual(1, len(glob.glob("testfiles/output/duplicity-new*.sigtar.gz")))
1443 # Confirm we can restore it (which in buggy versions, would fail)
1444 self.restore()
1445
1446=== modified file 'testing/functional/test_selection.py'
1447--- testing/functional/test_selection.py 2017-07-11 14:55:38 +0000
1448+++ testing/functional/test_selection.py 2017-12-01 23:01:42 +0000
1449@@ -1,3 +1,4 @@
1450+# -*- coding: utf-8 -*-
1451 # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
1452 #
1453 # Copyright 2014 Aaron Whitehouse <aaron@whitehouse.kiwi.nz>
1454@@ -21,6 +22,7 @@
1455 import os
1456 import sys
1457 import platform
1458+import io
1459
1460 import unittest
1461
1462@@ -91,57 +93,57 @@
1463 # --------- trailing_space sub2_file.txt (ea) # Excluded until trailing_space test, when (is)
1464
1465 complete_directory_tree = [
1466- ['1', '2', '3', 'trailing_space ', '1.doc', '1.py'],
1467- ['1sub1', '1sub2', '1sub3'],
1468- ['1sub1sub1', '1sub1sub2', '1sub1sub3'],
1469- ['1sub1sub1_file.txt'],
1470- ['1sub1sub2_file.txt'],
1471- ['1sub1sub3_file.txt'],
1472- ['1sub2sub1', '1sub2sub2', '1sub2sub3'],
1473- ['1sub3sub1', '1sub3sub2', '1sub3sub3'],
1474- ['2sub1', '2sub2', '2sub3'],
1475- ['2sub1sub1', '2sub1sub2', '2sub1sub3'],
1476- ['2sub1sub1_file.txt'],
1477- ['2sub2sub1', '2sub2sub2', '2sub2sub3'],
1478- ['2sub3sub1', '2sub3sub2', '2sub3sub3'],
1479- ['3sub1', '3sub2', '3sub3'],
1480- ['3sub1sub1', '3sub1sub2', '3sub1sub3'],
1481- ['3sub2sub1', '3sub2sub2', '3sub2sub3'],
1482- ['3sub3sub1', '3sub3sub2', '3sub3sub3'],
1483- ['3sub3sub2_file.txt'],
1484- ['trailing_space sub1', 'trailing_space sub2'],
1485- ['trailing_space sub2_file.txt']
1486+ [u"1", u"2", u"3", u"trailing_space ", u"1.doc", u"1.py"],
1487+ [u"1sub1", u"1sub2", u"1sub3"],
1488+ [u"1sub1sub1", u"1sub1sub2", u"1sub1sub3"],
1489+ [u"1sub1sub1_file.txt"],
1490+ [u"1sub1sub2_file.txt"],
1491+ [u"1sub1sub3_file.txt"],
1492+ [u"1sub2sub1", u"1sub2sub2", u"1sub2sub3"],
1493+ [u"1sub3sub1", u"1sub3sub2", u"1sub3sub3"],
1494+ [u"2sub1", u"2sub2", u"2sub3"],
1495+ [u"2sub1sub1", u"2sub1sub2", u"2sub1sub3"],
1496+ [u"2sub1sub1_file.txt"],
1497+ [u"2sub2sub1", u"2sub2sub2", u"2sub2sub3"],
1498+ [u"2sub3sub1", u"2sub3sub2", u"2sub3sub3"],
1499+ [u"3sub1", u"3sub2", u"3sub3"],
1500+ [u"3sub1sub1", u"3sub1sub2", u"3sub1sub3"],
1501+ [u"3sub2sub1", u"3sub2sub2", u"3sub2sub3"],
1502+ [u"3sub3sub1", u"3sub3sub2", u"3sub3sub3"],
1503+ [u"3sub3sub2_file.txt"],
1504+ [u"trailing_space sub1", u"trailing_space sub2"],
1505+ [u"trailing_space sub2_file.txt"]
1506 ]
1507
1508- expected_restored_tree = [['1', '2', '3', '1.py'],
1509- ['1sub1', '1sub2', '1sub3'],
1510- ['1sub1sub1', '1sub1sub3'],
1511- ['1sub1sub1_file.txt'],
1512- ['1sub2sub1'],
1513- ['1sub3sub3'],
1514- ['2sub1'],
1515- ['2sub1sub1'],
1516- ['2sub1sub1_file.txt'],
1517- ['3sub2', '3sub3'],
1518- ['3sub2sub1', '3sub2sub2', '3sub2sub3'],
1519- ['3sub3sub1', '3sub3sub2', '3sub3sub3'],
1520- ['3sub3sub2_file.txt']]
1521+ expected_restored_tree = [[u"1", u"2", u"3", u"1.py"],
1522+ [u"1sub1", u"1sub2", u"1sub3"],
1523+ [u"1sub1sub1", u"1sub1sub3"],
1524+ [u"1sub1sub1_file.txt"],
1525+ [u"1sub2sub1"],
1526+ [u"1sub3sub3"],
1527+ [u"2sub1"],
1528+ [u"2sub1sub1"],
1529+ [u"2sub1sub1_file.txt"],
1530+ [u"3sub2", u"3sub3"],
1531+ [u"3sub2sub1", u"3sub2sub2", u"3sub2sub3"],
1532+ [u"3sub3sub1", u"3sub3sub2", u"3sub3sub3"],
1533+ [u"3sub3sub2_file.txt"]]
1534
1535- expected_restored_tree_with_trailing_space = [['1', '2', '3', 'trailing_space ', '1.py'],
1536- ['1sub1', '1sub2', '1sub3'],
1537- ['1sub1sub1', '1sub1sub3'],
1538- ['1sub1sub1_file.txt'],
1539- ['1sub2sub1'],
1540- ['1sub3sub3'],
1541- ['2sub1'],
1542- ['2sub1sub1'],
1543- ['2sub1sub1_file.txt'],
1544- ['3sub2', '3sub3'],
1545- ['3sub2sub1', '3sub2sub2', '3sub2sub3'],
1546- ['3sub3sub1', '3sub3sub2', '3sub3sub3'],
1547- ['3sub3sub2_file.txt'],
1548- ['trailing_space sub1', 'trailing_space sub2'],
1549- ['trailing_space sub2_file.txt']]
1550+ expected_restored_tree_with_trailing_space = [[u"1", u"2", u"3", u"trailing_space ", u"1.py"],
1551+ [u"1sub1", u"1sub2", u"1sub3"],
1552+ [u"1sub1sub1", u"1sub1sub3"],
1553+ [u"1sub1sub1_file.txt"],
1554+ [u"1sub2sub1"],
1555+ [u"1sub3sub3"],
1556+ [u"2sub1"],
1557+ [u"2sub1sub1"],
1558+ [u"2sub1sub1_file.txt"],
1559+ [u"3sub2", u"3sub3"],
1560+ [u"3sub2sub1", u"3sub2sub2", u"3sub2sub3"],
1561+ [u"3sub3sub1", u"3sub3sub2", u"3sub3sub3"],
1562+ [u"3sub3sub2_file.txt"],
1563+ [u"trailing_space sub1", u"trailing_space sub2"],
1564+ [u"trailing_space sub2_file.txt"]]
1565
1566 def directory_tree_to_list_of_lists(self, parent_directory):
1567 """
1568@@ -167,7 +169,7 @@
1569
1570 def test_files_are_as_expected(self):
1571 """Test that the contents of testfiles/select are as expected."""
1572- testfiles = self.directory_tree_to_list_of_lists('testfiles/select2')
1573+ testfiles = self.directory_tree_to_list_of_lists(u"testfiles/select2")
1574 # print(testfiles)
1575 self.assertEqual(testfiles, self.complete_directory_tree)
1576
1577@@ -177,28 +179,28 @@
1578
1579 def test_include_exclude_basic(self):
1580 """ Test --include and --exclude work in the basic case """
1581- self.backup("full", "testfiles/select2",
1582- options=["--include", "testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt",
1583- "--exclude", "testfiles/select2/3/3sub3/3sub3sub2",
1584- "--include", "testfiles/select2/3/3sub2/3sub2sub2",
1585- "--include", "testfiles/select2/3/3sub3",
1586- "--exclude", "testfiles/select2/3/3sub1",
1587- "--exclude", "testfiles/select2/2/2sub1/2sub1sub3",
1588- "--exclude", "testfiles/select2/2/2sub1/2sub1sub2",
1589- "--include", "testfiles/select2/2/2sub1",
1590- "--exclude", "testfiles/select2/1/1sub3/1sub3sub2",
1591- "--exclude", "testfiles/select2/1/1sub3/1sub3sub1",
1592- "--exclude", "testfiles/select2/1/1sub2/1sub2sub3",
1593- "--include", "testfiles/select2/1/1sub2/1sub2sub1",
1594- "--exclude", "testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt",
1595- "--exclude", "testfiles/select2/1/1sub1/1sub1sub2",
1596- "--exclude", "testfiles/select2/1/1sub2",
1597- "--include", "testfiles/select2/1.py",
1598- "--include", "testfiles/select2/3",
1599- "--include", "testfiles/select2/1",
1600- "--exclude", "testfiles/select2/**"])
1601+ self.backup(u"full", u"testfiles/select2",
1602+ options=[u"--include", u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt",
1603+ u"--exclude", u"testfiles/select2/3/3sub3/3sub3sub2",
1604+ u"--include", u"testfiles/select2/3/3sub2/3sub2sub2",
1605+ u"--include", u"testfiles/select2/3/3sub3",
1606+ u"--exclude", u"testfiles/select2/3/3sub1",
1607+ u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub3",
1608+ u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub2",
1609+ u"--include", u"testfiles/select2/2/2sub1",
1610+ u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub2",
1611+ u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub1",
1612+ u"--exclude", u"testfiles/select2/1/1sub2/1sub2sub3",
1613+ u"--include", u"testfiles/select2/1/1sub2/1sub2sub1",
1614+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt",
1615+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub2",
1616+ u"--exclude", u"testfiles/select2/1/1sub2",
1617+ u"--include", u"testfiles/select2/1.py",
1618+ u"--include", u"testfiles/select2/3",
1619+ u"--include", u"testfiles/select2/1",
1620+ u"--exclude", u"testfiles/select2/**"])
1621 self.restore()
1622- restore_dir = 'testfiles/restore_out'
1623+ restore_dir = u"testfiles/restore_out"
1624 restored = self.directory_tree_to_list_of_lists(restore_dir)
1625 self.assertEqual(restored, self.expected_restored_tree)
1626
1627@@ -207,32 +209,32 @@
1628 # Note that, because this only passes items in as a list of options, this test does not test whether duplicity
1629 # would correctly interpret commandline options with spaces. However, bin/duplicity uses sys.argv[1:], which
1630 # should return a list of strings after having correctly processed quotes etc.
1631- self.backup("full", "testfiles/select2",
1632- options=["--include",
1633- "testfiles/select2/trailing_space /trailing_space sub2/trailing_space sub2_file.txt",
1634- "--exclude", "testfiles/select2/trailing_space /trailing_space sub2",
1635- "--include", "testfiles/select2/trailing_space ",
1636- "--include", "testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt",
1637- "--exclude", "testfiles/select2/3/3sub3/3sub3sub2",
1638- "--include", "testfiles/select2/3/3sub2/3sub2sub2",
1639- "--include", "testfiles/select2/3/3sub3",
1640- "--exclude", "testfiles/select2/3/3sub1",
1641- "--exclude", "testfiles/select2/2/2sub1/2sub1sub3",
1642- "--exclude", "testfiles/select2/2/2sub1/2sub1sub2",
1643- "--include", "testfiles/select2/2/2sub1",
1644- "--exclude", "testfiles/select2/1/1sub3/1sub3sub2",
1645- "--exclude", "testfiles/select2/1/1sub3/1sub3sub1",
1646- "--exclude", "testfiles/select2/1/1sub2/1sub2sub3",
1647- "--include", "testfiles/select2/1/1sub2/1sub2sub1",
1648- "--exclude", "testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt",
1649- "--exclude", "testfiles/select2/1/1sub1/1sub1sub2",
1650- "--exclude", "testfiles/select2/1/1sub2",
1651- "--include", "testfiles/select2/1.py",
1652- "--include", "testfiles/select2/3",
1653- "--include", "testfiles/select2/1",
1654- "--exclude", "testfiles/select2/**"])
1655+ self.backup(u"full", u"testfiles/select2",
1656+ options=[u"--include",
1657+ u"testfiles/select2/trailing_space /trailing_space sub2/trailing_space sub2_file.txt",
1658+ u"--exclude", u"testfiles/select2/trailing_space /trailing_space sub2",
1659+ u"--include", u"testfiles/select2/trailing_space ",
1660+ u"--include", u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt",
1661+ u"--exclude", u"testfiles/select2/3/3sub3/3sub3sub2",
1662+ u"--include", u"testfiles/select2/3/3sub2/3sub2sub2",
1663+ u"--include", u"testfiles/select2/3/3sub3",
1664+ u"--exclude", u"testfiles/select2/3/3sub1",
1665+ u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub3",
1666+ u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub2",
1667+ u"--include", u"testfiles/select2/2/2sub1",
1668+ u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub2",
1669+ u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub1",
1670+ u"--exclude", u"testfiles/select2/1/1sub2/1sub2sub3",
1671+ u"--include", u"testfiles/select2/1/1sub2/1sub2sub1",
1672+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt",
1673+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub2",
1674+ u"--exclude", u"testfiles/select2/1/1sub2",
1675+ u"--include", u"testfiles/select2/1.py",
1676+ u"--include", u"testfiles/select2/3",
1677+ u"--include", u"testfiles/select2/1",
1678+ u"--exclude", u"testfiles/select2/**"])
1679 self.restore()
1680- restore_dir = 'testfiles/restore_out'
1681+ restore_dir = u"testfiles/restore_out"
1682 restored = self.directory_tree_to_list_of_lists(restore_dir)
1683 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)
1684
1685@@ -246,29 +248,29 @@
1686 """Test that exclude filelist works in the basic case """
1687 # As this is an exclude filelist any lines with no +/- modifier should be treated as if they have a -.
1688 # Create a filelist
1689- with open('testfiles/exclude.txt', 'w') as f:
1690- f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1691- 'testfiles/select2/3/3sub3/3sub3sub2\n'
1692- '+ testfiles/select2/3/3sub2/3sub2sub2\n'
1693- '+ testfiles/select2/3/3sub3\n'
1694- '- testfiles/select2/3/3sub1\n' # - added to ensure it makes no difference
1695- 'testfiles/select2/2/2sub1/2sub1sub3\n'
1696- 'testfiles/select2/2/2sub1/2sub1sub2\n'
1697- '+ testfiles/select2/2/2sub1\n'
1698- 'testfiles/select2/1/1sub3/1sub3sub2\n'
1699- 'testfiles/select2/1/1sub3/1sub3sub1\n'
1700- 'testfiles/select2/1/1sub2/1sub2sub3\n'
1701- '+ testfiles/select2/1/1sub2/1sub2sub1\n'
1702- 'testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1703- 'testfiles/select2/1/1sub1/1sub1sub2\n'
1704- '- testfiles/select2/1/1sub2\n' # - added to ensure it makes no difference
1705- '+ testfiles/select2/1.py\n'
1706- '+ testfiles/select2/3\n'
1707- '+ testfiles/select2/1\n'
1708- 'testfiles/select2/**')
1709- self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
1710+ with io.open(u"testfiles/exclude.txt", u"w") as f:
1711+ f.write(u"+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1712+ u"testfiles/select2/3/3sub3/3sub3sub2\n"
1713+ u"+ testfiles/select2/3/3sub2/3sub2sub2\n"
1714+ u"+ testfiles/select2/3/3sub3\n"
1715+ u"- testfiles/select2/3/3sub1\n" # - added to ensure it makes no difference
1716+ u"testfiles/select2/2/2sub1/2sub1sub3\n"
1717+ u"testfiles/select2/2/2sub1/2sub1sub2\n"
1718+ u"+ testfiles/select2/2/2sub1\n"
1719+ u"testfiles/select2/1/1sub3/1sub3sub2\n"
1720+ u"testfiles/select2/1/1sub3/1sub3sub1\n"
1721+ u"testfiles/select2/1/1sub2/1sub2sub3\n"
1722+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n"
1723+ u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
1724+ u"testfiles/select2/1/1sub1/1sub1sub2\n"
1725+ u"- testfiles/select2/1/1sub2\n" # - added to ensure it makes no difference
1726+ u"+ testfiles/select2/1.py\n"
1727+ u"+ testfiles/select2/3\n"
1728+ u"+ testfiles/select2/1\n"
1729+ u"testfiles/select2/**")
1730+ self.backup(u"full", u"testfiles/select2", options=[u"--exclude-filelist=testfiles/exclude.txt"])
1731 self.restore()
1732- restore_dir = 'testfiles/restore_out'
1733+ restore_dir = u"testfiles/restore_out"
1734 restored = self.directory_tree_to_list_of_lists(restore_dir)
1735 self.assertEqual(restored, self.expected_restored_tree)
1736
1737@@ -285,33 +287,33 @@
1738 # * Unnecessarily quoted filenames with/without modifier (both " and ')
1739
1740 # Create a filelist
1741- with open('testfiles/exclude.txt', 'w') as f:
1742- f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1743- 'testfiles/select2/3/3sub3/3sub3sub2\n'
1744- '+ testfiles/select2/3/3sub2/3sub2sub2\n'
1745- ' + testfiles/select2/3/3sub3\n' # Note leading space added here
1746- '- testfiles/select2/3/3sub1\n'
1747- ' testfiles/select2/2/2sub1/2sub1sub3\n' # Note leading spaces added here
1748- '\n'
1749- 'testfiles/select2/2/2sub1/2sub1sub2\n'
1750- ' + testfiles/select2/2/2sub1 \n' # Note added trailing/leading space here
1751- '- "testfiles/select2/1/1sub3/1sub3sub2"\n' # Unnecessary quotes
1752- '# Testing a full-line comment\n'
1753- "'testfiles/select2/1/1sub3/1sub3sub1' \n" # Note added spaces and quotes here
1754- 'testfiles/select2/1/1sub2/1sub2sub3\n'
1755- ' \n'
1756- '+ testfiles/select2/1/1sub2/1sub2sub1\n'
1757- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1758- 'testfiles/select2/1/1sub1/1sub1sub2\n'
1759- ' # Testing a full-line comment with leading and trailing spaces \n'
1760- 'testfiles/select2/1/1sub2 \n' # Note added spaces here
1761- '+ testfiles/select2/1.py\n'
1762- '+ testfiles/select2/3 \n' # Note added space here
1763- '+ testfiles/select2/1\n'
1764- '- testfiles/select2/**')
1765- self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
1766+ with io.open(u"testfiles/exclude.txt", u"w") as f:
1767+ f.write(u"+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1768+ u"testfiles/select2/3/3sub3/3sub3sub2\n"
1769+ u"+ testfiles/select2/3/3sub2/3sub2sub2\n"
1770+ u" + testfiles/select2/3/3sub3\n" # Note leading space added here
1771+ u"- testfiles/select2/3/3sub1\n"
1772+ u" testfiles/select2/2/2sub1/2sub1sub3\n" # Note leading spaces added here
1773+ u"\n"
1774+ u"testfiles/select2/2/2sub1/2sub1sub2\n"
1775+ u" + testfiles/select2/2/2sub1 \n" # Note added trailing/leading space here
1776+ u'- "testfiles/select2/1/1sub3/1sub3sub2"\n' # Unnecessary quotes
1777+ u"# Testing a full-line comment\n"
1778+ u"'testfiles/select2/1/1sub3/1sub3sub1' \n" # Note added spaces and quotes here
1779+ u"testfiles/select2/1/1sub2/1sub2sub3\n"
1780+ u" \n"
1781+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n"
1782+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
1783+ u"testfiles/select2/1/1sub1/1sub1sub2\n"
1784+ u" # Testing a full-line comment with leading and trailing spaces \n"
1785+ u"testfiles/select2/1/1sub2 \n" # Note added spaces here
1786+ u"+ testfiles/select2/1.py\n"
1787+ u"+ testfiles/select2/3 \n" # Note added space here
1788+ u"+ testfiles/select2/1\n"
1789+ u"- testfiles/select2/**")
1790+ self.backup(u"full", u"testfiles/select2", options=[u"--exclude-filelist=testfiles/exclude.txt"])
1791 self.restore()
1792- restore_dir = 'testfiles/restore_out'
1793+ restore_dir = u"testfiles/restore_out"
1794 restored = self.directory_tree_to_list_of_lists(restore_dir)
1795 self.assertEqual(restored, self.expected_restored_tree)
1796
1797@@ -330,65 +332,65 @@
1798 # * Unnecessarily quoted filenames with/without modifier (both " and ')
1799
1800 # Create a filelist
1801- with open('testfiles/exclude.txt', 'w') as f:
1802- f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1803- 'testfiles/select2/3/3sub3/3sub3sub2\n'
1804- '+ testfiles/select2/3/3sub2/3sub2sub2\n'
1805- ' + testfiles/select2/3/3sub3\n' # Note leading space added here
1806- '- testfiles/select2/3/3sub1\n'
1807- ' testfiles/select2/2/2sub1/2sub1sub3\n' # Note leading spaces added here
1808- '\n'
1809- 'testfiles/select2/2/2sub1/2sub1sub2\n'
1810- ' + testfiles/select2/2/2sub1 \n' # Note added trailing/leading space here
1811- '- "testfiles/select2/1/1sub3/1sub3sub2"\n' # Unnecessary quotes
1812- '# Testing a full-line comment\n'
1813- "'testfiles/select2/1/1sub3/1sub3sub1' \n" # Note added spaces and quotes here
1814- 'testfiles/select2/1/1sub2/1sub2sub3\n'
1815- ' \n'
1816- '+ testfiles/select2/1/1sub2/1sub2sub1\n'
1817- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1818- 'testfiles/select2/1/1sub1/1sub1sub2\n'
1819- ' # Testing a full-line comment with leading and trailing spaces \n'
1820- 'testfiles/select2/1/1sub2 \n' # Note added spaces here
1821- '+ testfiles/select2/1.py\n'
1822- '+ testfiles/select2/3 \n' # Note added space here
1823- '+ testfiles/select2/1\n'
1824- '- testfiles/select2/**')
1825- self.backup("full", "testfiles/select2", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])
1826+ with io.open(u"testfiles/exclude.txt", u"w") as f:
1827+ f.write(u"+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1828+ u"testfiles/select2/3/3sub3/3sub3sub2\n"
1829+ u"+ testfiles/select2/3/3sub2/3sub2sub2\n"
1830+ u" + testfiles/select2/3/3sub3\n" # Note leading space added here
1831+ u"- testfiles/select2/3/3sub1\n"
1832+ u" testfiles/select2/2/2sub1/2sub1sub3\n" # Note leading spaces added here
1833+ u"\n"
1834+ u"testfiles/select2/2/2sub1/2sub1sub2\n"
1835+ u" + testfiles/select2/2/2sub1 \n" # Note added trailing/leading space here
1836+ u'- "testfiles/select2/1/1sub3/1sub3sub2"\n' # Unnecessary quotes
1837+ u"# Testing a full-line comment\n"
1838+ u"'testfiles/select2/1/1sub3/1sub3sub1' \n" # Note added spaces and quotes here
1839+ u"testfiles/select2/1/1sub2/1sub2sub3\n"
1840+ u" \n"
1841+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n"
1842+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
1843+ u"testfiles/select2/1/1sub1/1sub1sub2\n"
1844+ u" # Testing a full-line comment with leading and trailing spaces \n"
1845+ u"testfiles/select2/1/1sub2 \n" # Note added spaces here
1846+ u"+ testfiles/select2/1.py\n"
1847+ u"+ testfiles/select2/3 \n" # Note added space here
1848+ u"+ testfiles/select2/1\n"
1849+ u"- testfiles/select2/**")
1850+ self.backup(u"full", u"testfiles/select2", options=[u"--exclude-globbing-filelist=testfiles/exclude.txt"])
1851 self.restore()
1852- restore_dir = 'testfiles/restore_out'
1853+ restore_dir = u"testfiles/restore_out"
1854 restored = self.directory_tree_to_list_of_lists(restore_dir)
1855 self.assertEqual(restored, self.expected_restored_tree)
1856
1857 def test_exclude_filelist_trailing_whitespace_folders_work_with_quotes(self):
1858 """Test that folders with trailing whitespace in the names work correctly if they are enclosed in quotes"""
1859 # Create a filelist
1860- with open('testfiles/exclude.txt', 'w') as f:
1861- f.write('+ "testfiles/select2/trailing_space /trailing_space sub2/trailing_space sub2_file.txt"\n' # New
1862- '- "testfiles/select2/trailing_space /trailing_space sub2"\n' # New
1863- '+ "testfiles/select2/trailing_space "\n' # New
1864- '+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1865- 'testfiles/select2/3/3sub3/3sub3sub2\n'
1866- '+ testfiles/select2/3/3sub2/3sub2sub2\n'
1867- '+ testfiles/select2/3/3sub3\n'
1868- '- testfiles/select2/3/3sub1\n'
1869- 'testfiles/select2/2/2sub1/2sub1sub3\n'
1870- 'testfiles/select2/2/2sub1/2sub1sub2\n'
1871- '+ testfiles/select2/2/2sub1\n'
1872- 'testfiles/select2/1/1sub3/1sub3sub2\n'
1873- 'testfiles/select2/1/1sub3/1sub3sub1\n'
1874- 'testfiles/select2/1/1sub2/1sub2sub3\n'
1875- '+ testfiles/select2/1/1sub2/1sub2sub1\n'
1876- 'testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1877- 'testfiles/select2/1/1sub1/1sub1sub2\n'
1878- '- testfiles/select2/1/1sub2\n'
1879- '+ testfiles/select2/1.py\n'
1880- '+ testfiles/select2/3\n'
1881- '+ testfiles/select2/1\n'
1882- 'testfiles/select2/**')
1883- self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt"])
1884+ with io.open(u"testfiles/exclude.txt", u"w") as f:
1885+ f.write(u'+ "testfiles/select2/trailing_space /trailing_space sub2/trailing_space sub2_file.txt"\n' # New
1886+ u"- 'testfiles/select2/trailing_space /trailing_space sub2'\n" # New
1887+ u'+ "testfiles/select2/trailing_space "\n' # New
1888+ u"+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1889+ u"testfiles/select2/3/3sub3/3sub3sub2\n"
1890+ u"+ testfiles/select2/3/3sub2/3sub2sub2\n"
1891+ u"+ testfiles/select2/3/3sub3\n"
1892+ u"- testfiles/select2/3/3sub1\n"
1893+ u"testfiles/select2/2/2sub1/2sub1sub3\n"
1894+ u"testfiles/select2/2/2sub1/2sub1sub2\n"
1895+ u"+ testfiles/select2/2/2sub1\n"
1896+ u"testfiles/select2/1/1sub3/1sub3sub2\n"
1897+ u"testfiles/select2/1/1sub3/1sub3sub1\n"
1898+ u"testfiles/select2/1/1sub2/1sub2sub3\n"
1899+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n"
1900+ u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
1901+ u"testfiles/select2/1/1sub1/1sub1sub2\n"
1902+ u"- testfiles/select2/1/1sub2\n"
1903+ u"+ testfiles/select2/1.py\n"
1904+ u"+ testfiles/select2/3\n"
1905+ u"+ testfiles/select2/1\n"
1906+ u"testfiles/select2/**")
1907+ self.backup(u"full", u"testfiles/select2", options=[u"--exclude-filelist=testfiles/exclude.txt"])
1908 self.restore()
1909- restore_dir = 'testfiles/restore_out'
1910+ restore_dir = u"testfiles/restore_out"
1911 restored = self.directory_tree_to_list_of_lists(restore_dir)
1912 self.assertEqual(restored, self.expected_restored_tree_with_trailing_space)
1913
1914@@ -396,32 +398,32 @@
1915 """Test that exclude filelist is unaffected by the --progress option"""
1916 # Regression test for Bug #1264744 (https://bugs.launchpad.net/duplicity/+bug/1264744)
1917 # Create a filelist identical to that used in test_exclude_filelist
1918- with open('testfiles/exclude.txt', 'w') as f:
1919- f.write('+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1920- 'testfiles/select2/3/3sub3/3sub3sub2\n'
1921- '+ testfiles/select2/3/3sub2/3sub2sub2\n'
1922- '+ testfiles/select2/3/3sub3\n'
1923- '- testfiles/select2/3/3sub1\n' # - added to ensure it makes no difference
1924- 'testfiles/select2/2/2sub1/2sub1sub3\n'
1925- 'testfiles/select2/2/2sub1/2sub1sub2\n'
1926- '+ testfiles/select2/2/2sub1\n'
1927- 'testfiles/select2/1/1sub3/1sub3sub2\n'
1928- 'testfiles/select2/1/1sub3/1sub3sub1\n'
1929- 'testfiles/select2/1/1sub2/1sub2sub3\n'
1930- '+ testfiles/select2/1/1sub2/1sub2sub1\n'
1931- 'testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1932- 'testfiles/select2/1/1sub1/1sub1sub2\n'
1933- '- testfiles/select2/1/1sub2\n' # - added to ensure it makes no difference
1934- '+ testfiles/select2/1.py\n'
1935- '+ testfiles/select2/3\n'
1936- '+ testfiles/select2/1\n'
1937- 'testfiles/select2/**')
1938+ with io.open(u"testfiles/exclude.txt", u"w") as f:
1939+ f.write(u"+ testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1940+ u"testfiles/select2/3/3sub3/3sub3sub2\n"
1941+ u"+ testfiles/select2/3/3sub2/3sub2sub2\n"
1942+ u"+ testfiles/select2/3/3sub3\n"
1943+ u"- testfiles/select2/3/3sub1\n" # - added to ensure it makes no difference
1944+ u"testfiles/select2/2/2sub1/2sub1sub3\n"
1945+ u"testfiles/select2/2/2sub1/2sub1sub2\n"
1946+ u"+ testfiles/select2/2/2sub1\n"
1947+ u"testfiles/select2/1/1sub3/1sub3sub2\n"
1948+ u"testfiles/select2/1/1sub3/1sub3sub1\n"
1949+ u"testfiles/select2/1/1sub2/1sub2sub3\n"
1950+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n"
1951+ u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
1952+ u"testfiles/select2/1/1sub1/1sub1sub2\n"
1953+ u"- testfiles/select2/1/1sub2\n" # - added to ensure it makes no difference
1954+ u"+ testfiles/select2/1.py\n"
1955+ u"+ testfiles/select2/3\n"
1956+ u"+ testfiles/select2/1\n"
1957+ u"testfiles/select2/**")
1958
1959 # Backup the files exactly as in test_exclude_filelist, but with the --progress option
1960- self.backup("full", "testfiles/select2", options=["--exclude-filelist=testfiles/exclude.txt",
1961- "--progress"])
1962+ self.backup(u"full", u"testfiles/select2", options=[u"--exclude-filelist=testfiles/exclude.txt",
1963+ u"--progress"])
1964 self.restore()
1965- restore_dir = 'testfiles/restore_out'
1966+ restore_dir = u"testfiles/restore_out"
1967 restored = self.directory_tree_to_list_of_lists(restore_dir)
1968 # The restored files should match those restored in test_exclude_filelist
1969 self.assertEqual(restored, self.expected_restored_tree)
1970@@ -437,29 +439,29 @@
1971 # See test_exclude_filelist above for explanation of what is expected. As this is an include filelist
1972 # any lines with no +/- modifier should be treated as if they have a +.
1973 # Create a filelist
1974- with open('testfiles/include.txt', 'w') as f:
1975- f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
1976- '- testfiles/select2/3/3sub3/3sub3sub2\n'
1977- 'testfiles/select2/3/3sub2/3sub2sub2\n'
1978- '+ testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
1979- '- testfiles/select2/3/3sub1\n'
1980- '- testfiles/select2/2/2sub1/2sub1sub3\n'
1981- '- testfiles/select2/2/2sub1/2sub1sub2\n'
1982- 'testfiles/select2/2/2sub1\n'
1983- '- testfiles/select2/1/1sub3/1sub3sub2\n'
1984- '- testfiles/select2/1/1sub3/1sub3sub1\n'
1985- '- testfiles/select2/1/1sub2/1sub2sub3\n'
1986- '+ testfiles/select2/1/1sub2/1sub2sub1\n' # + added to ensure it makes no difference
1987- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
1988- '- testfiles/select2/1/1sub1/1sub1sub2\n'
1989- '- testfiles/select2/1/1sub2\n'
1990- 'testfiles/select2/1.py\n'
1991- 'testfiles/select2/3\n'
1992- 'testfiles/select2/1\n'
1993- '- testfiles/select2/**')
1994- self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
1995+ with io.open(u"testfiles/include.txt", u"w") as f:
1996+ f.write(u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
1997+ u"- testfiles/select2/3/3sub3/3sub3sub2\n"
1998+ u"testfiles/select2/3/3sub2/3sub2sub2\n"
1999+ u"+ testfiles/select2/3/3sub3\n" # + added to ensure it makes no difference
2000+ u"- testfiles/select2/3/3sub1\n"
2001+ u"- testfiles/select2/2/2sub1/2sub1sub3\n"
2002+ u"- testfiles/select2/2/2sub1/2sub1sub2\n"
2003+ u"testfiles/select2/2/2sub1\n"
2004+ u"- testfiles/select2/1/1sub3/1sub3sub2\n"
2005+ u"- testfiles/select2/1/1sub3/1sub3sub1\n"
2006+ u"- testfiles/select2/1/1sub2/1sub2sub3\n"
2007+ u"+ testfiles/select2/1/1sub2/1sub2sub1\n" # + added to ensure it makes no difference
2008+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
2009+ u"- testfiles/select2/1/1sub1/1sub1sub2\n"
2010+ u"- testfiles/select2/1/1sub2\n"
2011+ u"testfiles/select2/1.py\n"
2012+ u"testfiles/select2/3\n"
2013+ u"testfiles/select2/1\n"
2014+ u"- testfiles/select2/**")
2015+ self.backup(u"full", u"testfiles/select2", options=[u"--include-filelist=testfiles/include.txt"])
2016 self.restore()
2017- restore_dir = 'testfiles/restore_out'
2018+ restore_dir = u"testfiles/restore_out"
2019 restored = self.directory_tree_to_list_of_lists(restore_dir)
2020 self.assertEqual(restored, self.expected_restored_tree)
2021
2022@@ -475,33 +477,33 @@
2023 # * Full-line comments with # as the first character and with leading/trailing spaces
2024 # * Unnecessarily quoted filenames with/without modifier (both " and ')
2025 # Create a filelist
2026- with open('testfiles/include.txt', 'w') as f:
2027- f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
2028- '- testfiles/select2/3/3sub3/3sub3sub2\n'
2029- '"testfiles/select2/3/3sub2/3sub2sub2"\n'
2030- ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
2031- '- testfiles/select2/3/3sub1\n'
2032- '- testfiles/select2/2/2sub1/2sub1sub3\n'
2033- ' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
2034- 'testfiles/select2/2/2sub1 \n'
2035- '\n'
2036- '- testfiles/select2/1/1sub3/1sub3sub2\n'
2037- '- testfiles/select2/1/1sub3/1sub3sub1 \n'
2038- "- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
2039- ' \n'
2040- ' + testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
2041- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
2042- ' - testfiles/select2/1/1sub1/1sub1sub2 \n'
2043- '# Testing full-line comment\n'
2044- '- testfiles/select2/1/1sub2\n'
2045- "'testfiles/select2/1.py'\n"
2046- 'testfiles/select2/3\n'
2047- ' # Testing another full-line comment \n'
2048- 'testfiles/select2/1\n'
2049- '- testfiles/select2/**')
2050- self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
2051+ with io.open(u"testfiles/include.txt", u"w") as f:
2052+ f.write(u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
2053+ u"- testfiles/select2/3/3sub3/3sub3sub2\n"
2054+ u'"testfiles/select2/3/3sub2/3sub2sub2"\n'
2055+ u" + testfiles/select2/3/3sub3\n" # + added to ensure it makes no difference
2056+ u"- testfiles/select2/3/3sub1\n"
2057+ u"- testfiles/select2/2/2sub1/2sub1sub3\n"
2058+ u' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
2059+ u"testfiles/select2/2/2sub1 \n"
2060+ u"\n"
2061+ u"- testfiles/select2/1/1sub3/1sub3sub2\n"
2062+ u"- testfiles/select2/1/1sub3/1sub3sub1 \n"
2063+ u"- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
2064+ u" \n"
2065+ u" + testfiles/select2/1/1sub2/1sub2sub1 \n" # + added to ensure it makes no difference
2066+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
2067+ u" - testfiles/select2/1/1sub1/1sub1sub2 \n"
2068+ u"# Testing full-line comment\n"
2069+ u"- testfiles/select2/1/1sub2\n"
2070+ u"'testfiles/select2/1.py'\n"
2071+ u"testfiles/select2/3\n"
2072+ u" # Testing another full-line comment \n"
2073+ u"testfiles/select2/1\n"
2074+ u"- testfiles/select2/**")
2075+ self.backup(u"full", u"testfiles/select2", options=[u"--include-filelist=testfiles/include.txt"])
2076 self.restore()
2077- restore_dir = 'testfiles/restore_out'
2078+ restore_dir = u"testfiles/restore_out"
2079 restored = self.directory_tree_to_list_of_lists(restore_dir)
2080 self.assertEqual(restored, self.expected_restored_tree)
2081
2082@@ -519,37 +521,37 @@
2083 # * Full-line comments with # as the first character and with leading/trailing spaces
2084 # * Unnecessarily quoted filenames with/without modifier (both " and ')
2085 # Create a filelist
2086- with open('testfiles/include.txt', 'w') as f:
2087- f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
2088- 'testfiles/select2/3/3sub2/3sub2sub2 \n'
2089- ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
2090- ' - testfiles/select2/3/3sub1 \n'
2091- '- testfiles/select2/2/2sub1/2sub1sub3\n'
2092- '- testfiles/select2/2/2sub1/2sub1sub2\n'
2093- '"testfiles/select2/2/2sub1"\n'
2094- ' - testfiles/select2/2/2sub3 \n' # Added because of Bug #1408411
2095- '- testfiles/select2/2/2sub2\n' # Added because of Bug #1408411
2096- "- 'testfiles/select2/1/1sub3/1sub3sub2'\n"
2097- '\n'
2098- '- testfiles/select2/1/1sub3/1sub3sub1\n'
2099- '- testfiles/select2/1/1sub2/1sub2sub3\n'
2100- '- "testfiles/select2/1/1sub2/1sub2sub2"\n' # Added because of Bug #1408411
2101- '# This is a full-line comment\n'
2102- '+ testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
2103- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
2104- ' \n'
2105- '- testfiles/select2/1/1sub1/1sub1sub2\n'
2106- # '- testfiles/select2/1/1sub2\n' # Commented out because of Bug #1408411
2107- "'testfiles/select2/1.py'\n"
2108- ' # This is another full-line comment, with spaces \n'
2109- 'testfiles/select2/3\n'
2110- # '- testfiles/select2/2\n' # Commented out because of Bug #1408411
2111- 'testfiles/select2/1\n'
2112- '- "testfiles/select2/trailing_space "\n' # es instead of ea as no wildcard - **
2113- '- testfiles/select2/1.doc') # es instead of ea as no wildcard - **
2114- self.backup("full", "testfiles/select2", options=["--include-filelist=testfiles/include.txt"])
2115+ with io.open(u"testfiles/include.txt", u"w") as f:
2116+ f.write(u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
2117+ u"testfiles/select2/3/3sub2/3sub2sub2 \n"
2118+ u" + testfiles/select2/3/3sub3\n" # + added to ensure it makes no difference
2119+ u" - testfiles/select2/3/3sub1 \n"
2120+ u"- testfiles/select2/2/2sub1/2sub1sub3\n"
2121+ u"- testfiles/select2/2/2sub1/2sub1sub2\n"
2122+ u'"testfiles/select2/2/2sub1"\n'
2123+ u" - testfiles/select2/2/2sub3 \n" # Added because of Bug #1408411
2124+ u"- testfiles/select2/2/2sub2\n" # Added because of Bug #1408411
2125+ u"- 'testfiles/select2/1/1sub3/1sub3sub2'\n"
2126+ u"\n"
2127+ u"- testfiles/select2/1/1sub3/1sub3sub1\n"
2128+ u"- testfiles/select2/1/1sub2/1sub2sub3\n"
2129+ u'- "testfiles/select2/1/1sub2/1sub2sub2"\n' # Added because of Bug #1408411
2130+ u"# This is a full-line comment\n"
2131+ u"+ testfiles/select2/1/1sub2/1sub2sub1 \n" # + added to ensure it makes no difference
2132+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
2133+ u" \n"
2134+ u"- testfiles/select2/1/1sub1/1sub1sub2\n"
2135+ # u"- testfiles/select2/1/1sub2\n" # Commented out because of Bug #1408411
2136+ u"'testfiles/select2/1.py'\n"
2137+ u" # This is another full-line comment, with spaces \n"
2138+ u"testfiles/select2/3\n"
2139+ # u"- testfiles/select2/2\n" # Commented out because of Bug #1408411
2140+ u"testfiles/select2/1\n"
2141+ u'- "testfiles/select2/trailing_space "\n' # es instead of ea as no wildcard - **
2142+ u"- testfiles/select2/1.doc") # es instead of ea as no wildcard - **
2143+ self.backup(u"full", u"testfiles/select2", options=[u"--include-filelist=testfiles/include.txt"])
2144 self.restore()
2145- restore_dir = 'testfiles/restore_out'
2146+ restore_dir = u"testfiles/restore_out"
2147 restored = self.directory_tree_to_list_of_lists(restore_dir)
2148 self.assertEqual(restored, self.expected_restored_tree)
2149
2150@@ -567,33 +569,33 @@
2151 # * Full-line comments with # as the first character and with leading/trailing spaces
2152 # * Unnecessarily quoted filenames with/without modifier (both " and ')
2153 # Create a filelist
2154- with open('testfiles/include.txt', 'w') as f:
2155- f.write('testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n'
2156- '- testfiles/select2/3/3sub3/3sub3sub2\n'
2157- '"testfiles/select2/3/3sub2/3sub2sub2"\n'
2158- ' + testfiles/select2/3/3sub3\n' # + added to ensure it makes no difference
2159- '- testfiles/select2/3/3sub1\n'
2160- '- testfiles/select2/2/2sub1/2sub1sub3\n'
2161- ' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
2162- 'testfiles/select2/2/2sub1 \n'
2163- '\n'
2164- '- testfiles/select2/1/1sub3/1sub3sub2\n'
2165- '- testfiles/select2/1/1sub3/1sub3sub1 \n'
2166- "- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
2167- ' \n'
2168- ' + testfiles/select2/1/1sub2/1sub2sub1 \n' # + added to ensure it makes no difference
2169- '- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n'
2170- ' - testfiles/select2/1/1sub1/1sub1sub2 \n'
2171- '# Testing full-line comment\n'
2172- '- testfiles/select2/1/1sub2\n'
2173- "'testfiles/select2/1.py'\n"
2174- 'testfiles/select2/3\n'
2175- ' # Testing another full-line comment \n'
2176- 'testfiles/select2/1\n'
2177- '- testfiles/select2/**')
2178- self.backup("full", "testfiles/select2", options=["--include-globbing-filelist=testfiles/include.txt"])
2179+ with io.open(u"testfiles/include.txt", u"w") as f:
2180+ f.write(u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt\n"
2181+ u"- testfiles/select2/3/3sub3/3sub3sub2\n"
2182+ u'"testfiles/select2/3/3sub2/3sub2sub2"\n'
2183+ u" + testfiles/select2/3/3sub3\n" # + added to ensure it makes no difference
2184+ u"- testfiles/select2/3/3sub1\n"
2185+ u"- testfiles/select2/2/2sub1/2sub1sub3\n"
2186+ u' - "testfiles/select2/2/2sub1/2sub1sub2"\n'
2187+ u"testfiles/select2/2/2sub1 \n"
2188+ u"\n"
2189+ u"- testfiles/select2/1/1sub3/1sub3sub2\n"
2190+ u"- testfiles/select2/1/1sub3/1sub3sub1 \n"
2191+ u"- 'testfiles/select2/1/1sub2/1sub2sub3'\n"
2192+ u" \n"
2193+ u" + testfiles/select2/1/1sub2/1sub2sub1 \n" # + added to ensure it makes no difference
2194+ u"- testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt\n"
2195+ u" - testfiles/select2/1/1sub1/1sub1sub2 \n"
2196+ u"# Testing full-line comment\n"
2197+ u"- testfiles/select2/1/1sub2\n"
2198+ u"'testfiles/select2/1.py'\n"
2199+ u"testfiles/select2/3\n"
2200+ u" # Testing another full-line comment \n"
2201+ u"testfiles/select2/1\n"
2202+ u"- testfiles/select2/**")
2203+ self.backup(u"full", u"testfiles/select2", options=[u"--include-globbing-filelist=testfiles/include.txt"])
2204 self.restore()
2205- restore_dir = 'testfiles/restore_out'
2206+ restore_dir = u"testfiles/restore_out"
2207 restored = self.directory_tree_to_list_of_lists(restore_dir)
2208 self.assertEqual(restored, self.expected_restored_tree)
2209
2210@@ -605,54 +607,54 @@
2211 def write_filelist(self, filelist_name):
2212 """Used by the below tests to write the filelist"""
2213 assert filelist_name is not None
2214- with open(filelist_name, 'w') as f:
2215- f.write("+ testfiles/select/1/2/1\n"
2216- "- testfiles/select/1/2\n"
2217- "- testfiles/select/1/1\n"
2218- "- testfiles/select/1/3")
2219+ with io.open(filelist_name, u"w") as f:
2220+ f.write(u"+ testfiles/select/1/2/1\n"
2221+ u"- testfiles/select/1/2\n"
2222+ u"- testfiles/select/1/1\n"
2223+ u"- testfiles/select/1/3")
2224
2225 def restore_and_check(self):
2226 """Restores the backup and compares to what was expected (based on the filelist in write_filelist)"""
2227 self.restore()
2228- restore_dir = 'testfiles/restore_out'
2229+ restore_dir = u"testfiles/restore_out"
2230 restored = self.directory_tree_to_list_of_lists(restore_dir)
2231- self.assertEqual(restored, [['2'], ['1']])
2232+ self.assertEqual(restored, [[u"2"], [u"1"]])
2233
2234 def test_commandline_include_exclude(self):
2235 """test an excluded folder is included for included contents when using commandline includes and excludes"""
2236- self.backup("full", "testfiles/select/1",
2237- options=["--include", "testfiles/select/1/2/1",
2238- "--exclude", "testfiles/select/1/2",
2239- "--exclude", "testfiles/select/1/1",
2240- "--exclude", "testfiles/select/1/3"])
2241+ self.backup(u"full", u"testfiles/select/1",
2242+ options=[u"--include", u"testfiles/select/1/2/1",
2243+ u"--exclude", u"testfiles/select/1/2",
2244+ u"--exclude", u"testfiles/select/1/1",
2245+ u"--exclude", u"testfiles/select/1/3"])
2246 self.restore_and_check()
2247
2248 def test_include_globbing_filelist(self):
2249 """test an excluded folder is included for included contents with an include-globbing-filelist """
2250 # Deprecated, but include for now to ensure it keeps working until it is deliberately removed.
2251- self.write_filelist("testfiles/include.txt")
2252- self.backup("full", "testfiles/select/1", options=["--include-globbing-filelist=testfiles/include.txt"])
2253+ self.write_filelist(u"testfiles/include.txt")
2254+ self.backup(u"full", u"testfiles/select/1", options=[u"--include-globbing-filelist=testfiles/include.txt"])
2255 self.restore_and_check()
2256
2257 def test_exclude_globbing_filelist(self):
2258 """test an excluded folder is included for included contents with an exclude-globbing-filelist """
2259 # Deprecated, but include for now to ensure it keeps working until it is deliberately removed.
2260- self.write_filelist("testfiles/exclude.txt")
2261- self.backup("full", "testfiles/select/1", options=["--exclude-globbing-filelist=testfiles/exclude.txt"])
2262+ self.write_filelist(u"testfiles/exclude.txt")
2263+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-globbing-filelist=testfiles/exclude.txt"])
2264 self.restore_and_check()
2265
2266 def test_include_filelist(self):
2267 """test an excluded folder is included for included contents with an include-filelist (non-globbing) """
2268 # Regression test for Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)
2269- self.write_filelist("testfiles/include.txt")
2270- self.backup("full", "testfiles/select/1", options=["--include-filelist=testfiles/include.txt"])
2271+ self.write_filelist(u"testfiles/include.txt")
2272+ self.backup(u"full", u"testfiles/select/1", options=[u"--include-filelist=testfiles/include.txt"])
2273 self.restore_and_check()
2274
2275 def test_exclude_filelist(self):
2276 """test an excluded folder is included for included contents with an exclude-filelist (non-globbing) """
2277 # Regression test for Bug #1408411 (https://bugs.launchpad.net/duplicity/+bug/1408411)
2278- self.write_filelist("testfiles/exclude.txt")
2279- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/exclude.txt"])
2280+ self.write_filelist(u"testfiles/exclude.txt")
2281+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/exclude.txt"])
2282 self.restore_and_check()
2283
2284
2285@@ -664,112 +666,112 @@
2286 def restore_and_check(self):
2287 """Restores the backup and compares to what is expected."""
2288 self.restore()
2289- restore_dir = 'testfiles/restore_out'
2290+ restore_dir = u"testfiles/restore_out"
2291 restored = self.directory_tree_to_list_of_lists(restore_dir)
2292- self.assertEqual(restored, [['2'], ['1']])
2293+ self.assertEqual(restored, [[u"2"], [u"1"]])
2294
2295 def test_exclude_filelist_asterisks_none(self):
2296 """Basic exclude filelist."""
2297- with open("testfiles/filelist.txt", 'w') as f:
2298- f.write("+ testfiles/select/1/2/1\n"
2299- "- testfiles/select/1/2\n"
2300- "- testfiles/select/1/1\n"
2301- "- testfiles/select/1/3")
2302- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2303+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2304+ f.write(u"+ testfiles/select/1/2/1\n"
2305+ u"- testfiles/select/1/2\n"
2306+ u"- testfiles/select/1/1\n"
2307+ u"- testfiles/select/1/3")
2308+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2309 self.restore_and_check()
2310
2311 def test_exclude_filelist_asterisks_single(self):
2312 """Exclude filelist with asterisks replacing folders."""
2313 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
2314- with open("testfiles/filelist.txt", 'w') as f:
2315- f.write("+ */select/1/2/1\n"
2316- "- */select/1/2\n"
2317- "- testfiles/*/1/1\n"
2318- "- */*/1/3")
2319- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2320+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2321+ f.write(u"+ */select/1/2/1\n"
2322+ u"- */select/1/2\n"
2323+ u"- testfiles/*/1/1\n"
2324+ u"- */*/1/3")
2325+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2326 self.restore_and_check()
2327
2328 def test_exclude_filelist_asterisks_double_asterisks(self):
2329 """Exclude filelist with double asterisks replacing folders."""
2330 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
2331- with open("testfiles/filelist.txt", 'w') as f:
2332- f.write("+ **/1/2/1\n"
2333- "- **/1/2\n"
2334- "- **/select/1/1\n"
2335- "- testfiles/select/1/3")
2336- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2337+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2338+ f.write(u"+ **/1/2/1\n"
2339+ u"- **/1/2\n"
2340+ u"- **/select/1/1\n"
2341+ u"- testfiles/select/1/3")
2342+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2343 self.restore_and_check()
2344
2345 def test_commandline_asterisks_single_excludes_only(self):
2346 """test_commandline_include_exclude with single asterisks on exclude lines."""
2347- self.backup("full", "testfiles/select/1",
2348- options=["--include", "testfiles/select/1/2/1",
2349- "--exclude", "testfiles/*/1/2",
2350- "--exclude", "*/select/1/1",
2351- "--exclude", "*/select/1/3"])
2352+ self.backup(u"full", u"testfiles/select/1",
2353+ options=[u"--include", u"testfiles/select/1/2/1",
2354+ u"--exclude", u"testfiles/*/1/2",
2355+ u"--exclude", u"*/select/1/1",
2356+ u"--exclude", u"*/select/1/3"])
2357 self.restore_and_check()
2358
2359 def test_commandline_asterisks_single_both(self):
2360 """test_commandline_include_exclude with single asterisks on both exclude and include lines."""
2361 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
2362- self.backup("full", "testfiles/select/1",
2363- options=["--include", "*/select/1/2/1",
2364- "--exclude", "testfiles/*/1/2",
2365- "--exclude", "*/select/1/1",
2366- "--exclude", "*/select/1/3"])
2367+ self.backup(u"full", u"testfiles/select/1",
2368+ options=[u"--include", u"*/select/1/2/1",
2369+ u"--exclude", u"testfiles/*/1/2",
2370+ u"--exclude", u"*/select/1/1",
2371+ u"--exclude", u"*/select/1/3"])
2372 self.restore_and_check()
2373
2374 def test_commandline_asterisks_double_exclude_only(self):
2375 """test_commandline_include_exclude with double asterisks on exclude lines."""
2376- self.backup("full", "testfiles/select/1",
2377- options=["--include", "testfiles/select/1/2/1",
2378- "--exclude", "**/1/2",
2379- "--exclude", "**/1/1",
2380- "--exclude", "**/1/3"])
2381+ self.backup(u"full", u"testfiles/select/1",
2382+ options=[u"--include", u"testfiles/select/1/2/1",
2383+ u"--exclude", u"**/1/2",
2384+ u"--exclude", u"**/1/1",
2385+ u"--exclude", u"**/1/3"])
2386 self.restore_and_check()
2387
2388 def test_commandline_asterisks_double_both(self):
2389 """test_commandline_include_exclude with double asterisks on both exclude and include lines."""
2390 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
2391- self.backup("full", "testfiles/select/1",
2392- options=["--include", "**/1/2/1",
2393- "--exclude", "**/1/2",
2394- "--exclude", "**/1/1",
2395- "--exclude", "**/1/3"])
2396+ self.backup(u"full", u"testfiles/select/1",
2397+ options=[u"--include", u"**/1/2/1",
2398+ u"--exclude", u"**/1/2",
2399+ u"--exclude", u"**/1/1",
2400+ u"--exclude", u"**/1/3"])
2401 self.restore_and_check()
2402
2403 def test_single_and_double_asterisks(self):
2404 """This compares a backup using --include-globbing-filelist with a single and double *."""
2405- with open("testfiles/filelist.txt", 'w') as f:
2406- f.write("+ testfiles/select2/*\n"
2407- "- testfiles/select")
2408- self.backup("full", "testfiles/", options=["--include-globbing-filelist=testfiles/filelist.txt"])
2409- self.restore()
2410- restore_dir = 'testfiles/restore_out'
2411- restored = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
2412- with open("testfiles/filelist2.txt", 'w') as f:
2413- f.write("+ testfiles/select2/**\n"
2414- "- testfiles/select")
2415- self.backup("full", "testfiles/", options=["--include-globbing-filelist=testfiles/filelist2.txt"])
2416- self.restore()
2417- restore_dir = 'testfiles/restore_out'
2418- restored2 = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
2419+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2420+ f.write(u"+ testfiles/select2/*\n"
2421+ u"- testfiles/select")
2422+ self.backup(u"full", u"testfiles/", options=[u"--include-globbing-filelist=testfiles/filelist.txt"])
2423+ self.restore()
2424+ restore_dir = u"testfiles/restore_out"
2425+ restored = self.directory_tree_to_list_of_lists(restore_dir + u"/select2")
2426+ with io.open(u"testfiles/filelist2.txt", u"w") as f:
2427+ f.write(u"+ testfiles/select2/**\n"
2428+ u"- testfiles/select")
2429+ self.backup(u"full", u"testfiles/", options=[u"--include-globbing-filelist=testfiles/filelist2.txt"])
2430+ self.restore()
2431+ restore_dir = u"testfiles/restore_out"
2432+ restored2 = self.directory_tree_to_list_of_lists(restore_dir + u"/select2")
2433 self.assertEqual(restored, restored2)
2434
2435 def test_single_and_double_asterisks_includes_excludes(self):
2436 """This compares a backup using --includes/--excludes with a single and double *."""
2437- self.backup("full", "testfiles/",
2438- options=["--include", "testfiles/select2/*",
2439- "--exclude", "testfiles/select"])
2440- self.restore()
2441- restore_dir = 'testfiles/restore_out'
2442- restored = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
2443- self.backup("full", "testfiles/",
2444- options=["--include", "testfiles/select2/**",
2445- "--exclude", "testfiles/select"])
2446- self.restore()
2447- restore_dir = 'testfiles/restore_out'
2448- restored2 = self.directory_tree_to_list_of_lists(restore_dir + "/select2")
2449+ self.backup(u"full", u"testfiles/",
2450+ options=[u"--include", u"testfiles/select2/*",
2451+ u"--exclude", u"testfiles/select"])
2452+ self.restore()
2453+ restore_dir = u"testfiles/restore_out"
2454+ restored = self.directory_tree_to_list_of_lists(restore_dir + u"/select2")
2455+ self.backup(u"full", u"testfiles/",
2456+ options=[u"--include", u"testfiles/select2/**",
2457+ u"--exclude", u"testfiles/select"])
2458+ self.restore()
2459+ restore_dir = u"testfiles/restore_out"
2460+ restored2 = self.directory_tree_to_list_of_lists(restore_dir + u"/select2")
2461 self.assertEqual(restored, restored2)
2462
2463
2464@@ -780,62 +782,62 @@
2465 def restore_and_check(self):
2466 """Restores the backup and compares to what is expected."""
2467 self.restore()
2468- restore_dir = 'testfiles/restore_out'
2469+ restore_dir = u"testfiles/restore_out"
2470 restored = self.directory_tree_to_list_of_lists(restore_dir)
2471- self.assertEqual(restored, [['2'], ['1']])
2472+ self.assertEqual(restored, [[u"2"], [u"1"]])
2473
2474 def test_exclude_filelist_trailing_slashes(self):
2475 """test_exclude_filelist_asterisks_none with trailing slashes."""
2476- with open("testfiles/filelist.txt", 'w') as f:
2477- f.write("+ testfiles/select/1/2/1/\n"
2478- "- testfiles/select/1/2/\n"
2479- "- testfiles/select/1/1/\n"
2480- "- testfiles/select/1/3/")
2481- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2482+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2483+ f.write(u"+ testfiles/select/1/2/1/\n"
2484+ u"- testfiles/select/1/2/\n"
2485+ u"- testfiles/select/1/1/\n"
2486+ u"- testfiles/select/1/3/")
2487+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2488 self.restore_and_check()
2489
2490 def test_exclude_filelist_trailing_slashes_single_wildcards_excludes(self):
2491 """test_exclude_filelist_trailing_slashes with single wildcards in excludes."""
2492 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
2493- with open("testfiles/filelist.txt", 'w') as f:
2494- f.write("+ testfiles/select/1/2/1/\n"
2495- "- */select/1/2/\n"
2496- "- testfiles/*/1/1/\n"
2497- "- */*/1/3/")
2498- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2499+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2500+ f.write(u"+ testfiles/select/1/2/1/\n"
2501+ u"- */select/1/2/\n"
2502+ u"- testfiles/*/1/1/\n"
2503+ u"- */*/1/3/")
2504+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2505 self.restore_and_check()
2506
2507 def test_exclude_filelist_trailing_slashes_double_wildcards_excludes(self):
2508 """test_exclude_filelist_trailing_slashes with double wildcards in excludes."""
2509 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
2510- with open("testfiles/filelist.txt", 'w') as f:
2511- f.write("+ testfiles/select/1/2/1/\n"
2512- "- **/1/2/\n"
2513- "- **/1/1/\n"
2514- "- **/1/3/")
2515- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2516+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2517+ f.write(u"+ testfiles/select/1/2/1/\n"
2518+ u"- **/1/2/\n"
2519+ u"- **/1/1/\n"
2520+ u"- **/1/3/")
2521+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2522 self.restore_and_check()
2523
2524 def test_exclude_filelist_trailing_slashes_double_wildcards_excludes_2(self):
2525 """second test_exclude_filelist_trailing_slashes with double wildcards in excludes."""
2526 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482) and
2527 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
2528- with open("testfiles/filelist.txt", 'w') as f:
2529- f.write("+ **/1/2/1/\n"
2530- "- **/1/2/\n"
2531- "- **/1/1/\n"
2532- "- **/1/3/")
2533- self.backup("full", "testfiles/select/1", options=["--exclude-filelist=testfiles/filelist.txt"])
2534+ with io.open(u"testfiles/filelist.txt", u"w") as f:
2535+ f.write(u"+ **/1/2/1/\n"
2536+ u"- **/1/2/\n"
2537+ u"- **/1/1/\n"
2538+ u"- **/1/3/")
2539+ self.backup(u"full", u"testfiles/select/1", options=[u"--exclude-filelist=testfiles/filelist.txt"])
2540 self.restore_and_check()
2541
2542 def test_exclude_filelist_trailing_slashes_wildcards(self):
2543 """test_commandline_asterisks_single_excludes_only with trailing slashes."""
2544 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
2545- self.backup("full", "testfiles/select/1",
2546- options=["--include", "testfiles/select/1/2/1/",
2547- "--exclude", "testfiles/*/1/2/",
2548- "--exclude", "*/select/1/1/",
2549- "--exclude", "*/select/1/3/"])
2550+ self.backup(u"full", u"testfiles/select/1",
2551+ options=[u"--include", u"testfiles/select/1/2/1/",
2552+ u"--exclude", u"testfiles/*/1/2/",
2553+ u"--exclude", u"*/select/1/1/",
2554+ u"--exclude", u"*/select/1/3/"])
2555 self.restore_and_check()
2556
2557
2558@@ -845,49 +847,49 @@
2559
2560 def test_no_trailing_slash(self):
2561 """ Test that including 1.py works as expected"""
2562- self.backup("full", "testfiles/select2",
2563- options=["--include", "testfiles/select2/1.py",
2564- "--exclude", "**"])
2565+ self.backup(u"full", u"testfiles/select2",
2566+ options=[u"--include", u"testfiles/select2/1.py",
2567+ u"--exclude", u"**"])
2568 self.restore()
2569- restore_dir = 'testfiles/restore_out'
2570+ restore_dir = u"testfiles/restore_out"
2571 restored = self.directory_tree_to_list_of_lists(restore_dir)
2572- self.assertEqual(restored, [['1.py']])
2573+ self.assertEqual(restored, [[u"1.py"]])
2574
2575 def test_trailing_slash(self):
2576 """ Test that globs with a trailing slash only match directories"""
2577 # Regression test for Bug #1479545
2578 # (https://bugs.launchpad.net/duplicity/+bug/1479545)
2579- self.backup("full", "testfiles/select2",
2580- options=["--include", "testfiles/select2/1.py/",
2581- "--exclude", "**"])
2582+ self.backup(u"full", u"testfiles/select2",
2583+ options=[u"--include", u"testfiles/select2/1.py/",
2584+ u"--exclude", u"**"])
2585 self.restore()
2586- restore_dir = 'testfiles/restore_out'
2587+ restore_dir = u"testfiles/restore_out"
2588 restored = self.directory_tree_to_list_of_lists(restore_dir)
2589 self.assertEqual(restored, [])
2590
2591 def test_include_files_not_subdirectories(self):
2592 """ Test that a trailing slash glob followed by a * glob only matches
2593 files and not subdirectories"""
2594- self.backup("full", "testfiles/select2",
2595- options=["--exclude", "testfiles/select2/*/",
2596- "--include", "testfiles/select2/*",
2597- "--exclude", "**"])
2598+ self.backup(u"full", u"testfiles/select2",
2599+ options=[u"--exclude", u"testfiles/select2/*/",
2600+ u"--include", u"testfiles/select2/*",
2601+ u"--exclude", u"**"])
2602 self.restore()
2603- restore_dir = 'testfiles/restore_out'
2604+ restore_dir = u"testfiles/restore_out"
2605 restored = self.directory_tree_to_list_of_lists(restore_dir)
2606- self.assertEqual(restored, [['1.doc', '1.py']])
2607+ self.assertEqual(restored, [[u"1.doc", u"1.py"]])
2608
2609 def test_include_subdirectories_not_files(self):
2610 """ Test that a trailing slash glob only matches directories"""
2611- self.backup("full", "testfiles/select2",
2612- options=["--include", "testfiles/select2/1/1sub1/**/",
2613- "--exclude", "testfiles/select2/1/1sub1/**",
2614- "--exclude", "**"])
2615+ self.backup(u"full", u"testfiles/select2",
2616+ options=[u"--include", u"testfiles/select2/1/1sub1/**/",
2617+ u"--exclude", u"testfiles/select2/1/1sub1/**",
2618+ u"--exclude", u"**"])
2619 self.restore()
2620- restore_dir = 'testfiles/restore_out'
2621+ restore_dir = u"testfiles/restore_out"
2622 restored = self.directory_tree_to_list_of_lists(restore_dir)
2623- self.assertEqual(restored, [['1'], ['1sub1'],
2624- ['1sub1sub1', '1sub1sub2', '1sub1sub3']])
2625+ self.assertEqual(restored, [[u"1"], [u"1sub1"],
2626+ [u"1sub1sub1", u"1sub1sub2", u"1sub1sub3"]])
2627
2628
2629 class TestGlobbingReplacement(IncludeExcludeFunctionalTest):
2630@@ -905,25 +907,25 @@
2631 # Identical to test_include_exclude_basic with globbing characters added to both include and exclude lines
2632 # Exhibits the issue reported in Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371).
2633 # See above and the unit tests for more granularity on the issue.
2634- self.backup("full", "testfiles/select2",
2635- options=["--include", "testfiles/select2/**/3sub3sub2/3sub3su?2_file.txt", # Note ** and ? added
2636- "--exclude", "testfiles/select2/*/3s*1", # Note * added in both directory and filename
2637- "--exclude", "testfiles/select2/**/2sub1sub3", # Note ** added
2638- "--exclude", "ignorecase:testfiles/select2/2/2sub1/2Sub1Sub2", # Note ignorecase added
2639- "--include", "ignorecase:testfiles/sel[w,u,e,q]ct2/2/2S?b1", # Note ignorecase, [] and
2640+ self.backup(u"full", u"testfiles/select2",
2641+ options=[u"--include", u"testfiles/select2/**/3sub3sub2/3sub3su?2_file.txt", # Note ** and ? added
2642+ u"--exclude", u"testfiles/select2/*/3s*1", # Note * added in both directory and filename
2643+ u"--exclude", u"testfiles/select2/**/2sub1sub3", # Note ** added
2644+ u"--exclude", u"ignorecase:testfiles/select2/2/2sub1/2Sub1Sub2", # Note ignorecase added
2645+ u"--include", u"ignorecase:testfiles/sel[w,u,e,q]ct2/2/2S?b1", # Note ignorecase, [] and
2646 # ? added
2647- "--exclude", "testfiles/select2/1/1sub3/1s[w,u,p,q]b3sub2", # Note [] added
2648- "--exclude", "testfiles/select2/1/1sub[1-4]/1sub3sub1", # Note [range] added
2649- "--include", "testfiles/select2/*/1sub2/1s[w,u,p,q]b2sub1", # Note * and [] added
2650- "--exclude", "testfiles/select2/1/1sub1/1sub1sub3/1su?1sub3_file.txt", # Note ? added
2651- "--exclude", "testfiles/select2/1/1*1/1sub1sub2", # Note * added
2652- "--exclude", "testfiles/select2/1/1sub2",
2653- "--include", "testfiles/select[2-4]/*.py", # Note * and [range] added
2654- "--include", "testfiles/*2/3", # Note * added
2655- "--include", "**/select2/1", # Note ** added
2656- "--exclude", "testfiles/select2/**"])
2657+ u"--exclude", u"testfiles/select2/1/1sub3/1s[w,u,p,q]b3sub2", # Note [] added
2658+ u"--exclude", u"testfiles/select2/1/1sub[1-4]/1sub3sub1", # Note [range] added
2659+ u"--include", u"testfiles/select2/*/1sub2/1s[w,u,p,q]b2sub1", # Note * and [] added
2660+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/1su?1sub3_file.txt", # Note ? added
2661+ u"--exclude", u"testfiles/select2/1/1*1/1sub1sub2", # Note * added
2662+ u"--exclude", u"testfiles/select2/1/1sub2",
2663+ u"--include", u"testfiles/select[2-4]/*.py", # Note * and [range] added
2664+ u"--include", u"testfiles/*2/3", # Note * added
2665+ u"--include", u"**/select2/1", # Note ** added
2666+ u"--exclude", u"testfiles/select2/**"])
2667 self.restore()
2668- restore_dir = 'testfiles/restore_out'
2669+ restore_dir = u"testfiles/restore_out"
2670 restored = self.directory_tree_to_list_of_lists(restore_dir)
2671 self.assertEqual(restored, self.expected_restored_tree)
2672
2673@@ -933,40 +935,40 @@
2674
2675 def test_exclude_if_present_baseline(self):
2676 """ Test that duplicity normally backs up files"""
2677- with open("testfiles/select2/1/1sub1/1sub1sub1/.nobackup", "w") as tag:
2678- tag.write("Files in this folder should not be backed up.")
2679- self.backup("full", "testfiles/select2/1/1sub1",
2680- options=["--include", "testfiles/select2/1/1sub1/1sub1sub1/*",
2681- "--exclude", "**"])
2682+ with io.open(u"testfiles/select2/1/1sub1/1sub1sub1/.nobackup", u"w") as tag:
2683+ tag.write(u"Files in this folder should not be backed up.")
2684+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2685+ options=[u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/*",
2686+ u"--exclude", u"**"])
2687 self.restore()
2688- restore_dir = 'testfiles/restore_out'
2689+ restore_dir = u"testfiles/restore_out"
2690 restored = self.directory_tree_to_list_of_lists(restore_dir)
2691- self.assertEqual(restored, [['1sub1sub1'],
2692- ['.nobackup', '1sub1sub1_file.txt']])
2693+ self.assertEqual(restored, [[u"1sub1sub1"],
2694+ [u".nobackup", u"1sub1sub1_file.txt"]])
2695
2696 def test_exclude_if_present_excludes(self):
2697 """ Test that duplicity excludes files with relevant tag"""
2698- with open("testfiles/select2/1/1sub1/1sub1sub1/.nobackup", "w") as tag:
2699- tag.write("Files in this folder should not be backed up.")
2700- self.backup("full", "testfiles/select2/1/1sub1",
2701- options=["--exclude-if-present", ".nobackup",
2702- "--include", "testfiles/select2/1/1sub1/1sub1sub1/*",
2703- "--exclude", "**"])
2704+ with io.open(u"testfiles/select2/1/1sub1/1sub1sub1/.nobackup", u"w") as tag:
2705+ tag.write(u"Files in this folder should not be backed up.")
2706+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2707+ options=[u"--exclude-if-present", u".nobackup",
2708+ u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/*",
2709+ u"--exclude", u"**"])
2710 self.restore()
2711- restore_dir = 'testfiles/restore_out'
2712+ restore_dir = u"testfiles/restore_out"
2713 restored = self.directory_tree_to_list_of_lists(restore_dir)
2714 self.assertEqual(restored, [])
2715
2716 def test_exclude_if_present_excludes_2(self):
2717 """ Test that duplicity excludes files with relevant tag"""
2718- with open("testfiles/select2/1/1sub1/1sub1sub1/EXCLUDE.tag", "w") as tag:
2719- tag.write("Files in this folder should also not be backed up.")
2720- self.backup("full", "testfiles/select2/1/1sub1",
2721- options=["--exclude-if-present", "EXCLUDE.tag",
2722- "--include", "testfiles/select2/1/1sub1/1sub1sub1/*",
2723- "--exclude", "**"])
2724+ with io.open(u"testfiles/select2/1/1sub1/1sub1sub1/EXCLUDE.tag", u"w") as tag:
2725+ tag.write(u"Files in this folder should also not be backed up.")
2726+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2727+ options=[u"--exclude-if-present", u"EXCLUDE.tag",
2728+ u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/*",
2729+ u"--exclude", u"**"])
2730 self.restore()
2731- restore_dir = 'testfiles/restore_out'
2732+ restore_dir = u"testfiles/restore_out"
2733 restored = self.directory_tree_to_list_of_lists(restore_dir)
2734 self.assertEqual(restored, [])
2735
2736@@ -974,42 +976,42 @@
2737 class TestLockedFoldersNoError(IncludeExcludeFunctionalTest):
2738 """ This tests that inaccessible folders do not cause an error"""
2739
2740- @unittest.skipUnless(platform.platform().startswith('Linux'),
2741- 'Skip on non-Linux systems')
2742+ @unittest.skipUnless(platform.platform().startswith("Linux"),
2743+ u"Skip on non-Linux systems")
2744 def test_locked_baseline(self):
2745 """ Test no error if locked in path but excluded"""
2746- folder_to_lock = "testfiles/select2/1/1sub1/1sub1sub3"
2747+ folder_to_lock = u"testfiles/select2/1/1sub1/1sub1sub3"
2748 initial_mode = os.stat(folder_to_lock).st_mode
2749 os.chmod(folder_to_lock, 0o0000)
2750- self.backup("full", "testfiles/select2/1/1sub1",
2751- options=["--include", "testfiles/select2/1/1sub1/1sub1sub1/*",
2752- "--exclude", "**"])
2753+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2754+ options=[u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/*",
2755+ u"--exclude", u"**"])
2756 os.chmod(folder_to_lock, initial_mode)
2757 self.restore()
2758- restore_dir = 'testfiles/restore_out'
2759+ restore_dir = u"testfiles/restore_out"
2760 restored = self.directory_tree_to_list_of_lists(restore_dir)
2761- self.assertEqual(restored, [['1sub1sub1'],
2762- ['1sub1sub1_file.txt']])
2763+ self.assertEqual(restored, [[u"1sub1sub1"],
2764+ [u"1sub1sub1_file.txt"]])
2765
2766- @unittest.skipUnless(platform.platform().startswith('Linux'),
2767- 'Skip on non-Linux systems')
2768+ @unittest.skipUnless(platform.platform().startswith("Linux"),
2769+ u"Skip on non-Linux systems")
2770 def test_locked_excl_if_present(self):
2771 """ Test no error if excluded locked with --exclude-if-present"""
2772 # Regression test for Bug #1620085
2773 # https://bugs.launchpad.net/duplicity/+bug/1620085
2774- folder_to_lock = "testfiles/select2/1/1sub1/1sub1sub3"
2775+ folder_to_lock = u"testfiles/select2/1/1sub1/1sub1sub3"
2776 initial_mode = os.stat(folder_to_lock).st_mode
2777 os.chmod(folder_to_lock, 0o0000)
2778- self.backup("full", "testfiles/select2/1/1sub1",
2779- options=["--exclude-if-present", "EXCLUDE.tag",
2780- "--include", "testfiles/select2/1/1sub1/1sub1sub1/*",
2781- "--exclude", "**"])
2782+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2783+ options=[u"--exclude-if-present", u"EXCLUDE.tag",
2784+ u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/*",
2785+ u"--exclude", u"**"])
2786 os.chmod(folder_to_lock, initial_mode)
2787 self.restore()
2788- restore_dir = 'testfiles/restore_out'
2789+ restore_dir = u"testfiles/restore_out"
2790 restored = self.directory_tree_to_list_of_lists(restore_dir)
2791- self.assertEqual(restored, [['1sub1sub1'],
2792- ['1sub1sub1_file.txt']])
2793+ self.assertEqual(restored, [[u"1sub1sub1"],
2794+ [u"1sub1sub1_file.txt"]])
2795
2796
2797 class TestFolderIncludesFiles(IncludeExcludeFunctionalTest):
2798@@ -1018,73 +1020,73 @@
2799
2800 def test_includes_files(self):
2801 """This tests that including a folder includes the files within it"""
2802- self.backup("full", "testfiles/select2/1/1sub1",
2803- options=["--include", "testfiles/select2/1/1sub1/1sub1sub1",
2804- "--exclude", "**"])
2805+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2806+ options=[u"--include", u"testfiles/select2/1/1sub1/1sub1sub1",
2807+ u"--exclude", u"**"])
2808 self.restore()
2809- restore_dir = 'testfiles/restore_out'
2810+ restore_dir = u"testfiles/restore_out"
2811 restored = self.directory_tree_to_list_of_lists(restore_dir)
2812- self.assertEqual(restored, [['1sub1sub1'],
2813- ['1sub1sub1_file.txt']])
2814+ self.assertEqual(restored, [[u"1sub1sub1"],
2815+ [u"1sub1sub1_file.txt"]])
2816
2817 def test_includes_files_trailing_slash(self):
2818 """This tests that including a folder includes the files within it"""
2819- self.backup("full", "testfiles/select2/1/1sub1",
2820- options=["--include", "testfiles/select2/1/1sub1/1sub1sub1/",
2821- "--exclude", "**"])
2822+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2823+ options=[u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/",
2824+ u"--exclude", u"**"])
2825 self.restore()
2826- restore_dir = 'testfiles/restore_out'
2827+ restore_dir = u"testfiles/restore_out"
2828 restored = self.directory_tree_to_list_of_lists(restore_dir)
2829- self.assertEqual(restored, [['1sub1sub1'],
2830- ['1sub1sub1_file.txt']])
2831+ self.assertEqual(restored, [[u"1sub1sub1"],
2832+ [u"1sub1sub1_file.txt"]])
2833
2834 def test_includes_files_trailing_slash_globbing_chars(self):
2835 """Tests folder includes with globbing char and /"""
2836- self.backup("full", "testfiles/select2/1/1sub1",
2837- options=["--include", "testfiles/s?lect2/1/1sub1/1sub1sub1/",
2838- "--exclude", "**"])
2839+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2840+ options=[u"--include", u"testfiles/s?lect2/1/1sub1/1sub1sub1/",
2841+ u"--exclude", u"**"])
2842 self.restore()
2843- restore_dir = 'testfiles/restore_out'
2844+ restore_dir = u"testfiles/restore_out"
2845 restored = self.directory_tree_to_list_of_lists(restore_dir)
2846- self.assertEqual(restored, [['1sub1sub1'],
2847- ['1sub1sub1_file.txt']])
2848+ self.assertEqual(restored, [[u"1sub1sub1"],
2849+ [u"1sub1sub1_file.txt"]])
2850
2851 def test_excludes_files_no_trailing_slash(self):
2852 """This tests that excluding a folder excludes the files within it"""
2853- self.backup("full", "testfiles/select2/1/1sub1",
2854- options=["--exclude", "testfiles/select2/1/1sub1/1sub1sub1",
2855- "--exclude", "testfiles/select2/1/1sub1/1sub1sub2",
2856- "--exclude", "testfiles/select2/1/1sub1/1sub1sub3",
2857- "--include", "testfiles/select2/1/1sub1/1sub1**",
2858- "--exclude", "testfiles/select2/1/1sub1/irrelevant.txt"])
2859+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2860+ options=[u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub1",
2861+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub2",
2862+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3",
2863+ u"--include", u"testfiles/select2/1/1sub1/1sub1**",
2864+ u"--exclude", u"testfiles/select2/1/1sub1/irrelevant.txt"])
2865 self.restore()
2866- restore_dir = 'testfiles/restore_out'
2867+ restore_dir = u"testfiles/restore_out"
2868 restored = self.directory_tree_to_list_of_lists(restore_dir)
2869 self.assertEqual(restored, [])
2870
2871 def test_excludes_files_trailing_slash(self):
2872 """Excluding a folder excludes the files within it, if ends with /"""
2873- self.backup("full", "testfiles/select2/1/1sub1",
2874- options=["--exclude", "testfiles/select2/1/1sub1/1sub1sub1/",
2875- "--exclude", "testfiles/select2/1/1sub1/1sub1sub2/",
2876- "--exclude", "testfiles/select2/1/1sub1/1sub1sub3/",
2877- "--include", "testfiles/select2/1/1sub1/1sub1**",
2878- "--exclude", "testfiles/select2/1/1sub1/irrelevant.txt"])
2879+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2880+ options=[u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub1/",
2881+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub2/",
2882+ u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/",
2883+ u"--include", u"testfiles/select2/1/1sub1/1sub1**",
2884+ u"--exclude", u"testfiles/select2/1/1sub1/irrelevant.txt"])
2885 self.restore()
2886- restore_dir = 'testfiles/restore_out'
2887+ restore_dir = u"testfiles/restore_out"
2888 restored = self.directory_tree_to_list_of_lists(restore_dir)
2889 self.assertEqual(restored, [])
2890
2891 def test_excludes_files_trailing_slash_globbing_chars(self):
2892 """Tests folder excludes with globbing char and /"""
2893- self.backup("full", "testfiles/select2/1/1sub1",
2894- options=["--exclude", "testfiles/sel?ct2/1/1sub1/1sub1sub1/",
2895- "--exclude", "testfiles/sel[e,f]ct2/1/1sub1/1sub1sub2/",
2896- "--exclude", "testfiles/sel*t2/1/1sub1/1sub1sub3/",
2897- "--include", "testfiles/select2/1/1sub1/1sub1**",
2898- "--exclude", "testfiles/select2/1/1sub1/irrelevant.txt"])
2899+ self.backup(u"full", u"testfiles/select2/1/1sub1",
2900+ options=[u"--exclude", u"testfiles/sel?ct2/1/1sub1/1sub1sub1/",
2901+ u"--exclude", u"testfiles/sel[e,f]ct2/1/1sub1/1sub1sub2/",
2902+ u"--exclude", u"testfiles/sel*t2/1/1sub1/1sub1sub3/",
2903+ u"--include", u"testfiles/select2/1/1sub1/1sub1**",
2904+ u"--exclude", u"testfiles/select2/1/1sub1/irrelevant.txt"])
2905 self.restore()
2906- restore_dir = 'testfiles/restore_out'
2907+ restore_dir = u"testfiles/restore_out"
2908 restored = self.directory_tree_to_list_of_lists(restore_dir)
2909 self.assertEqual(restored, [])
2910
2911@@ -1094,30 +1096,110 @@
2912
2913 def test_absolute_paths_non_globbing(self):
2914 """ Test --include and --exclude work with absolute paths"""
2915- self.backup("full", os.path.abspath("testfiles/select2"),
2916- options=["--include", os.path.abspath("testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt"),
2917- "--exclude", os.path.abspath("testfiles/select2/3/3sub3/3sub3sub2"),
2918- "--include", os.path.abspath("testfiles/select2/3/3sub2/3sub2sub2"),
2919- "--include", os.path.abspath("testfiles/select2/3/3sub3"),
2920- "--exclude", os.path.abspath("testfiles/select2/3/3sub1"),
2921- "--exclude", os.path.abspath("testfiles/select2/2/2sub1/2sub1sub3"),
2922- "--exclude", os.path.abspath("testfiles/select2/2/2sub1/2sub1sub2"),
2923- "--include", os.path.abspath("testfiles/select2/2/2sub1"),
2924- "--exclude", os.path.abspath("testfiles/select2/1/1sub3/1sub3sub2"),
2925- "--exclude", os.path.abspath("testfiles/select2/1/1sub3/1sub3sub1"),
2926- "--exclude", os.path.abspath("testfiles/select2/1/1sub2/1sub2sub3"),
2927- "--include", os.path.abspath("testfiles/select2/1/1sub2/1sub2sub1"),
2928- "--exclude", os.path.abspath("testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt"),
2929- "--exclude", os.path.abspath("testfiles/select2/1/1sub1/1sub1sub2"),
2930- "--exclude", os.path.abspath("testfiles/select2/1/1sub2"),
2931- "--include", os.path.abspath("testfiles/select2/1.py"),
2932- "--include", os.path.abspath("testfiles/select2/3"),
2933- "--include", os.path.abspath("testfiles/select2/1"),
2934- "--exclude", os.path.abspath("testfiles/select2/**")])
2935+ self.backup(u"full", os.path.abspath(u"testfiles/select2"),
2936+ options=[u"--include", os.path.abspath(u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt"),
2937+ u"--exclude", os.path.abspath(u"testfiles/select2/3/3sub3/3sub3sub2"),
2938+ u"--include", os.path.abspath(u"testfiles/select2/3/3sub2/3sub2sub2"),
2939+ u"--include", os.path.abspath(u"testfiles/select2/3/3sub3"),
2940+ u"--exclude", os.path.abspath(u"testfiles/select2/3/3sub1"),
2941+ u"--exclude", os.path.abspath(u"testfiles/select2/2/2sub1/2sub1sub3"),
2942+ u"--exclude", os.path.abspath(u"testfiles/select2/2/2sub1/2sub1sub2"),
2943+ u"--include", os.path.abspath(u"testfiles/select2/2/2sub1"),
2944+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub3/1sub3sub2"),
2945+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub3/1sub3sub1"),
2946+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub2/1sub2sub3"),
2947+ u"--include", os.path.abspath(u"testfiles/select2/1/1sub2/1sub2sub1"),
2948+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt"),
2949+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub1/1sub1sub2"),
2950+ u"--exclude", os.path.abspath(u"testfiles/select2/1/1sub2"),
2951+ u"--include", os.path.abspath(u"testfiles/select2/1.py"),
2952+ u"--include", os.path.abspath(u"testfiles/select2/3"),
2953+ u"--include", os.path.abspath(u"testfiles/select2/1"),
2954+ u"--exclude", os.path.abspath(u"testfiles/select2/**")])
2955 self.restore()
2956- restore_dir = 'testfiles/restore_out'
2957+ restore_dir = u"testfiles/restore_out"
2958 restored = self.directory_tree_to_list_of_lists(restore_dir)
2959 self.assertEqual(restored, self.expected_restored_tree)
2960
2961+
2962+@unittest.skipUnless(sys.getfilesystemencoding() == "UTF-8",
2963+ u"Skipping TestUnicode -- Only tested to work on UTF-8 systems")
2964+class TestUnicode(IncludeExcludeFunctionalTest):
2965+ """ Tests include/exclude options with unicode paths"""
2966+
2967+ def test_unicode_paths_non_globbing(self):
2968+ """ Test --include and --exclude work with unicode paths"""
2969+ self.backup(u"full", u"testfiles/select-unicode",
2970+ options=[u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/Παράδειγμα/उदाहरण.txt",
2971+ u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/Παράδειγμα/דוגמא.txt",
2972+ u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/მაგალითი/",
2973+ u"--include", u"testfiles/select-unicode/прыклад/пример/例/",
2974+ u"--exclude", u"testfiles/select-unicode/прыклад/пример/",
2975+ u"--include", u"testfiles/select-unicode/прыклад/",
2976+ u"--include", u"testfiles/select-unicode/օրինակ.txt",
2977+ u"--exclude", u"testfiles/select-unicode/**"])
2978+ self.restore()
2979+ restore_dir = u"testfiles/restore_out"
2980+ restored = self.directory_tree_to_list_of_lists(restore_dir)
2981+ self.assertEqual(restored, [[u"прыклад", u"օրինակ.txt"],
2982+ [u"пример", u"উদাহরণ"], [u"例"], [u"Παράδειγμα"], [u"ઉદાહરણ.log"]])
2983+
2984+ def test_unicode_paths_asterisks(self):
2985+ """ Test --include and --exclude work with unicode paths and globs containing * and **"""
2986+ p = u"testfiles/select-unicode/"
2987+ self.backup(u"full", u"testfiles/select-unicode",
2988+ options=[u"--exclude", p + u"прыклад/пример/例/Παρά*ειγμα/उदाहरण.txt", # Note *
2989+ u"--exclude", p + u"прыклад/пример/例/Παράδειγμα/דוגמא.txt",
2990+ u"--exclude", p + u"прыклад/пример/例/მაგალითი/",
2991+ u"--include", p + u"пр**/例/", # Note **
2992+ u"--exclude", p + u"прыклад/пример/",
2993+ u"--include", p + u"прыкла*/", # Note *
2994+ u"--include", p + u"օր*ակ.txt", # Note *
2995+ u"--exclude", p + u"**"])
2996+ self.restore()
2997+ restore_dir = u"testfiles/restore_out"
2998+ restored = self.directory_tree_to_list_of_lists(restore_dir)
2999+ self.assertEqual(restored, [[u"прыклад", u"օրինակ.txt"],
3000+ [u"пример", u"উদাহরণ"], [u"例"], [u"Παράδειγμα"], [u"ઉદાહરણ.log"]])
3001+
3002+ def test_unicode_paths_square_brackets(self):
3003+ """ Test --include and --exclude work with unicode paths with character options in []s and [!]s"""
3004+ p = u"testfiles/select-unicode/"
3005+ self.backup(u"full", u"testfiles/select-unicode",
3006+ options=[u"--exclude", p + u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt",
3007+ u"--exclude", p + u"пры[к,и,р]лад/пример/例/Παράδειγμα/דוגמא.txt",
3008+ u"--exclude", p + u"прыклад/пр[!a,b,c]мер/例/მაგალითი/",
3009+ u"--include", p + u"прыклад/при[g,м,д]ер/例/",
3010+ u"--exclude", p + u"прыклад/пример/",
3011+ u"--include", p + u"прыклад/",
3012+ u"--include", p + u"օրինակ.txt",
3013+ u"--exclude", p + u"**"])
3014+ self.restore()
3015+ restore_dir = u"testfiles/restore_out"
3016+ restored = self.directory_tree_to_list_of_lists(restore_dir)
3017+ self.assertEqual(restored, [[u"прыклад", u"օրինակ.txt"],
3018+ [u"пример", u"উদাহরণ"], [u"例"], [u"Παράδειγμα"], [u"ઉદાહરણ.log"]])
3019+
3020+ def test_unicode_filelist(self):
3021+ """Test that exclude filelist works with unicode filenames"""
3022+ # As this is an exclude filelist any lines with no +/- modifier should be treated as if they have a -.
3023+ path = u"testfiles/select-unicode/"
3024+ # Create a filelist
3025+ with io.open(u"testfiles/exclude.txt", u"w", encoding="UTF-8") as f:
3026+ f.write(u"- " + path + u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt\n"
3027+ u"- " + path + u"прыклад/пример/例/Παράδειγμα/דוגמא.txt\n"
3028+ u"- " + path + u"прыклад/пример/例/მაგალითი/\n"
3029+ u"+ " + path + u"прыклад/пример/例/\n"
3030+ u"- " + path + u"прыклад/пример/\n"
3031+ u"+ " + path + u"прыклад/\n"
3032+ u"+ " + path + u"օրինակ.txt\n"
3033+ u"- " + path + u"**")
3034+ self.backup(u"full", path, options=[u"--exclude-filelist=testfiles/exclude.txt"])
3035+ self.restore()
3036+ restore_dir = u"testfiles/restore_out"
3037+ restored = self.directory_tree_to_list_of_lists(restore_dir)
3038+ self.assertEqual(restored, [[u"прыклад", u"օրինակ.txt"],
3039+ [u"пример", u"উদাহরণ"], [u"例"], [u"Παράδειγμα"], [u"ઉદાહરણ.log"]])
3040+
3041 if __name__ == "__main__":
3042 unittest.main()
3043
3044=== modified file 'testing/functional/test_verify.py'
3045--- testing/functional/test_verify.py 2015-01-01 13:07:31 +0000
3046+++ testing/functional/test_verify.py 2017-12-01 23:01:42 +0000
3047@@ -32,20 +32,20 @@
3048 """
3049 def test_verify(self):
3050 """Test that verify (without --compare-data) works in the basic case"""
3051- self.backup("full", "testfiles/various_file_types", options=[])
3052- self.verify('testfiles/various_file_types/executable', file_to_verify='executable', options=[])
3053+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3054+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable', options=[])
3055
3056 def test_verify_changed_source_file(self):
3057 """Test verify (without --compare-data) gives no error if a source file is changed"""
3058 # This test was made to pass in fixing Bug #1354880
3059- self.backup("full", "testfiles/various_file_types", options=[])
3060+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3061
3062 # Edit source file
3063 with open('testfiles/various_file_types/executable', 'r+') as f:
3064 f.write('This changes a source file.')
3065
3066 # Test verify for the file
3067- self.verify('testfiles/various_file_types/executable', file_to_verify='executable', options=[])
3068+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable', options=[])
3069
3070 def test_verify_changed_source_file_adjust_mtime(self):
3071 """Test verify (without --compare-data) gives no error if a source file is changed and the mtime is changed
3072@@ -58,7 +58,7 @@
3073 # the times from a stat call don't match what a utime will set.
3074 os.utime('testfiles/various_file_types/executable', (file_info.st_atime, file_info.st_mtime))
3075
3076- self.backup("full", "testfiles/various_file_types", options=[])
3077+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3078
3079 # Edit source file
3080 with open('testfiles/various_file_types/executable', 'r+') as f:
3081@@ -68,19 +68,19 @@
3082 os.utime('testfiles/various_file_types/executable', (file_info.st_atime, file_info.st_mtime))
3083
3084 # Test verify for the file
3085- self.verify('testfiles/various_file_types/executable', file_to_verify='executable', options=[])
3086+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable', options=[])
3087
3088 def test_verify_compare_data(self):
3089 """Test that verify works in the basic case when the --compare-data option is used"""
3090- self.backup("full", "testfiles/various_file_types", options=[])
3091+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3092
3093 # Test verify for the file with --compare-data
3094- self.verify('testfiles/various_file_types/executable', file_to_verify='executable',
3095- options=["--compare-data"])
3096+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable',
3097+ options=[u"--compare-data"])
3098
3099 def test_verify_compare_data_changed_source_file(self):
3100 """Test verify with --compare-data gives an error if a source file is changed"""
3101- self.backup("full", "testfiles/various_file_types", options=[])
3102+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3103
3104 # Edit source file
3105 with open('testfiles/various_file_types/executable', 'r+') as f:
3106@@ -88,8 +88,8 @@
3107
3108 # Test verify for edited file fails with --compare-data
3109 try:
3110- self.verify('testfiles/various_file_types/executable', file_to_verify='executable',
3111- options=["--compare-data"])
3112+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable',
3113+ options=[u"--compare-data"])
3114 except CmdError as e:
3115 self.assertEqual(e.exit_status, 1, str(e))
3116 else:
3117@@ -105,7 +105,7 @@
3118 # the times from a stat call don't match what a utime will set
3119 os.utime('testfiles/various_file_types/executable', (file_info.st_atime, file_info.st_mtime))
3120
3121- self.backup("full", "testfiles/various_file_types", options=[])
3122+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3123 # Edit source file
3124 with open('testfiles/various_file_types/executable', 'r+') as f:
3125 f.write('This changes a source file.')
3126@@ -115,8 +115,8 @@
3127
3128 # Test verify for edited file fails with --compare-data
3129 try:
3130- self.verify('testfiles/various_file_types/executable', file_to_verify='executable',
3131- options=["--compare-data"])
3132+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable',
3133+ options=[u"--compare-data"])
3134 except CmdError as e:
3135 self.assertEqual(e.exit_status, 1, str(e))
3136 else:
3137@@ -124,7 +124,7 @@
3138
3139 def test_verify_corrupt_archive(self):
3140 """Test verify (without --compare-data) gives an error if the archive is corrupted"""
3141- self.backup("full", "testfiles/various_file_types", options=[])
3142+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3143 output_files = os.listdir("testfiles/output")
3144 archives = [elem for elem in output_files if "vol" in elem]
3145 for archive in archives:
3146@@ -133,7 +133,7 @@
3147 f.write('This writes text into each archive file to corrupt it.')
3148 # Test verify for the file
3149 try:
3150- self.verify('testfiles/various_file_types/executable', file_to_verify='executable', options=[])
3151+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable', options=[])
3152 except CmdError as e:
3153 # Should return a 21 error code for "hash mismatch"
3154 self.assertEqual(e.exit_status, 21, str(e))
3155@@ -142,7 +142,7 @@
3156
3157 def test_verify_corrupt_archive_compare_data(self):
3158 """Test verify with --compare-data gives an error if the archive is corrupted"""
3159- self.backup("full", "testfiles/various_file_types", options=[])
3160+ self.backup(u"full", u"testfiles/various_file_types", options=[])
3161 output_files = os.listdir("testfiles/output")
3162 archives = [elem for elem in output_files if "vol" in elem]
3163 for archive in archives:
3164@@ -151,8 +151,8 @@
3165 f.write('This writes text into each archive file to corrupt it.')
3166 # Test verify for the file
3167 try:
3168- self.verify('testfiles/various_file_types/executable', file_to_verify='executable',
3169- options=["--compare-data"])
3170+ self.verify(u'testfiles/various_file_types/executable', file_to_verify=u'executable',
3171+ options=[u"--compare-data"])
3172 except CmdError as e:
3173 # Should return a 21 error code for "hash mismatch"
3174 self.assertEqual(e.exit_status, 21, str(e))
3175
3176=== added file 'testing/testfiles.tar.gz'
3177Binary files testing/testfiles.tar.gz 1970-01-01 00:00:00 +0000 and testing/testfiles.tar.gz 2017-12-01 23:01:42 +0000 differ
3178=== removed file 'testing/testfiles.tar.gz'
3179Binary files testing/testfiles.tar.gz 2017-11-14 16:53:17 +0000 and testing/testfiles.tar.gz 1970-01-01 00:00:00 +0000 differ
3180=== modified file 'testing/unit/test_diffdir.py'
3181--- testing/unit/test_diffdir.py 2017-01-18 22:59:29 +0000
3182+++ testing/unit/test_diffdir.py 2017-12-01 23:01:42 +0000
3183@@ -20,8 +20,6 @@
3184 # along with duplicity; if not, write to the Free Software Foundation,
3185 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3186
3187-import os
3188-import sys
3189 import unittest
3190
3191 from duplicity.path import * # @UnusedWildImport
3192
3193=== modified file 'testing/unit/test_globmatch.py'
3194--- testing/unit/test_globmatch.py 2017-07-11 14:55:38 +0000
3195+++ testing/unit/test_globmatch.py 2017-12-01 23:01:42 +0000
3196@@ -1,3 +1,4 @@
3197+# -*- coding: utf-8 -*-
3198 # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3199 #
3200 # Copyright 2002 Ben Escoto <ben@emerose.org>
3201@@ -20,6 +21,8 @@
3202 # along with duplicity; if not, write to the Free Software Foundation,
3203 # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3204
3205+import unittest
3206+
3207 from duplicity.globmatch import *
3208 from duplicity.path import *
3209 from . import UnitTestCase
3210@@ -75,14 +78,14 @@
3211
3212 def test_glob_to_regex(self):
3213 """test_glob_re - test translation of shell pattern to regular exp"""
3214- self.assertEqual(glob_to_regex("hello"), "hello")
3215- self.assertEqual(glob_to_regex(".e?ll**o"), "\\.e[^/]ll.*o")
3216- self.assertEqual(glob_to_regex("[abc]el[^de][!fg]h"),
3217- "[abc]el[^de][^fg]h")
3218- self.assertEqual(glob_to_regex("/usr/*/bin/"),
3219- "\\/usr\\/[^/]*\\/bin\\/")
3220- self.assertEqual(glob_to_regex("[a.b/c]"), "[a.b/c]")
3221- self.assertEqual(glob_to_regex("[a*b-c]e[!]]"), "[a*b-c]e[^]]")
3222+ self.assertEqual(glob_to_regex(u"hello"), u"hello")
3223+ self.assertEqual(glob_to_regex(u".e?ll**o"), u"\\.e[^/]ll.*o")
3224+ self.assertEqual(glob_to_regex(u"[abc]el[^de][!fg]h"),
3225+ u"[abc]el[^de][^fg]h")
3226+ self.assertEqual(glob_to_regex(u"/usr/*/bin/"),
3227+ u"\\/usr\\/[^/]*\\/bin\\/")
3228+ self.assertEqual(glob_to_regex(u"[a.b/c]"), u"[a.b/c]")
3229+ self.assertEqual(glob_to_regex(u"[a*b-c]e[!]]"), u"[a*b-c]e[^]]")
3230
3231
3232 class TestSelectValuesFromGlobs(UnitTestCase):
3233@@ -91,22 +94,22 @@
3234 def test_glob_scans_parent_directories(self):
3235 """Test glob scans parent"""
3236 self.assertEqual(
3237- inc_sel_dir("testfiles/parent/sub", "testfiles/parent"), 2)
3238+ inc_sel_dir(u"testfiles/parent/sub", u"testfiles/parent"), 2)
3239 self.assertEqual(
3240- inc_sel_dir("testfiles/select2/3/3sub2", "testfiles/select2/3"), 2)
3241+ inc_sel_dir(u"testfiles/select2/3/3sub2", u"testfiles/select2/3"), 2)
3242
3243 def test_double_asterisk_include(self):
3244 """Test a few globbing patterns, including **"""
3245- self.assertEqual(inc_sel_file("**", "foo.txt"), 1)
3246- self.assertEqual(inc_sel_dir("**", "folder"), 1)
3247+ self.assertEqual(inc_sel_file(u"**", u"foo.txt"), 1)
3248+ self.assertEqual(inc_sel_dir(u"**", u"folder"), 1)
3249
3250 def test_double_asterisk_extension_include(self):
3251 """Test **.py"""
3252- self.assertEqual(inc_sel_file("**.py", "what/ever.py"), 1)
3253- self.assertEqual(inc_sel_file("**.py", "what/ever.py/foo"), 1)
3254- self.assertEqual(inc_sel_dir("**.py", "foo"), 2)
3255- self.assertEqual(inc_sel_dir("**.py", "usr/local/bin"), 2)
3256- self.assertEqual(inc_sel_dir("**.py", "/usr/local/bin"), 2)
3257+ self.assertEqual(inc_sel_file(u"**.py", u"what/ever.py"), 1)
3258+ self.assertEqual(inc_sel_file(u"**.py", u"what/ever.py/foo"), 1)
3259+ self.assertEqual(inc_sel_dir(u"**.py", u"foo"), 2)
3260+ self.assertEqual(inc_sel_dir(u"**.py", u"usr/local/bin"), 2)
3261+ self.assertEqual(inc_sel_dir(u"**.py", u"/usr/local/bin"), 2)
3262
3263
3264 class TestTrailingSlash(UnitTestCase):
3265@@ -115,95 +118,95 @@
3266 def test_trailing_slash_matches_only_dirs(self):
3267 """Test matching where glob includes a trailing slash"""
3268 # Test the folder named "folder" is included
3269- self.assertEqual(inc_sel_dir("fold*/", "folder"), 1)
3270+ self.assertEqual(inc_sel_dir(u"fold*/", u"folder"), 1)
3271
3272 # Test the file (not folder) named "folder" is not included
3273- self.assertEqual(inc_sel_file("fold*/", "folder"), None)
3274- self.assertEqual(inc_sel_file("folder/", "folder"), None)
3275+ self.assertEqual(inc_sel_file(u"fold*/", u"folder"), None)
3276+ self.assertEqual(inc_sel_file(u"folder/", u"folder"), None)
3277
3278 # Test miscellaneous file/folder
3279- self.assertEqual(inc_sel_file("fo*/", "foo.txt"), None)
3280+ self.assertEqual(inc_sel_file(u"fo*/", u"foo.txt"), None)
3281
3282 def test_included_files_are_matched_no_slash(self):
3283 """Test that files within an included folder are matched"""
3284- self.assertEqual(inc_sel_file("fold*", "folder/file.txt"), 1)
3285- self.assertEqual(inc_sel_file("fold*", "folder/file.txt"), 1)
3286- self.assertEqual(inc_sel_file("fold*", "folder/2/file.txt"), 1)
3287+ self.assertEqual(inc_sel_file(u"fold*", u"folder/file.txt"), 1)
3288+ self.assertEqual(inc_sel_file(u"fold*", u"folder/file.txt"), 1)
3289+ self.assertEqual(inc_sel_file(u"fold*", u"folder/2/file.txt"), 1)
3290
3291 def test_included_files_are_matched_no_slash_2(self):
3292 """Test that files within an included folder are matched"""
3293- self.assertEqual(inc_sel_file("folder", "folder/file.txt"), 1)
3294- self.assertEqual(inc_sel_file("folder/2", "folder/2/file.txt"), 1)
3295+ self.assertEqual(inc_sel_file(u"folder", u"folder/file.txt"), 1)
3296+ self.assertEqual(inc_sel_file(u"folder/2", u"folder/2/file.txt"), 1)
3297
3298 def test_included_files_are_matched_slash(self):
3299 """Test that files within an included folder are matched with /"""
3300 # Bug #1624725
3301 # https://bugs.launchpad.net/duplicity/+bug/1624725
3302- self.assertEqual(inc_sel_file("folder/", "folder/file.txt"), 1)
3303+ self.assertEqual(inc_sel_file(u"folder/", u"folder/file.txt"), 1)
3304
3305 def test_included_files_are_matched_slash_2(self):
3306 """Test that files within an included folder are matched with /"""
3307 # Bug #1624725
3308 # https://bugs.launchpad.net/duplicity/+bug/1624725
3309 self.assertEqual(inc_sel_file(
3310- "testfiles/select2/1/1sub1/1sub1sub1/",
3311- "testfiles/select2/1/1sub1/1sub1sub1/1sub1sub1_file.txt"), 1)
3312+ u"testfiles/select2/1/1sub1/1sub1sub1/",
3313+ u"testfiles/select2/1/1sub1/1sub1sub1/1sub1sub1_file.txt"), 1)
3314
3315 def test_included_files_are_matched_slash_2_parents(self):
3316 """Test that duplicity will scan parent of glob/"""
3317 # Bug #1624725
3318 # https://bugs.launchpad.net/duplicity/+bug/1624725
3319 self.assertEqual(inc_sel_dir(
3320- "testfiles/select2/1/1sub1/1sub1sub1/",
3321- "testfiles/select2/1/1sub1/1sub1sub1"), 1)
3322+ u"testfiles/select2/1/1sub1/1sub1sub1/",
3323+ u"testfiles/select2/1/1sub1/1sub1sub1"), 1)
3324 self.assertEqual(inc_sel_dir(
3325- "testfiles/select2/1/1sub1/1sub1sub1/",
3326- "testfiles/select2/1/1sub1"), 2)
3327+ u"testfiles/select2/1/1sub1/1sub1sub1/",
3328+ u"testfiles/select2/1/1sub1"), 2)
3329
3330 def test_included_files_are_matched_slash_wildcard(self):
3331 """Test that files within an included folder are matched with /"""
3332 # Bug #1624725
3333 # https://bugs.launchpad.net/duplicity/+bug/1624725
3334- self.assertEqual(inc_sel_file("fold*/", "folder/file.txt"), 1)
3335+ self.assertEqual(inc_sel_file(u"fold*/", u"folder/file.txt"), 1)
3336
3337 def test_slash_matches_everything(self):
3338 """Test / matches everything"""
3339- self.assertEqual(inc_sel_dir("/", "/tmp/testfiles/select/1/2"), 1)
3340- self.assertEqual(inc_sel_dir("/", "/test/random/path"), 1)
3341- self.assertEqual(exc_sel_dir("/", "/test/random/path"), 0)
3342- self.assertEqual(inc_sel_dir("/", "/"), 1)
3343- self.assertEqual(inc_sel_dir("/", "/var/log"), 1)
3344- self.assertEqual(inc_sel_file("/", "/var/log/log.txt"), 1)
3345+ self.assertEqual(inc_sel_dir(u"/", u"/tmp/testfiles/select/1/2"), 1)
3346+ self.assertEqual(inc_sel_dir(u"/", u"/test/random/path"), 1)
3347+ self.assertEqual(exc_sel_dir(u"/", u"/test/random/path"), 0)
3348+ self.assertEqual(inc_sel_dir(u"/", u"/"), 1)
3349+ self.assertEqual(inc_sel_dir(u"/", u"/var/log"), 1)
3350+ self.assertEqual(inc_sel_file(u"/", u"/var/log/log.txt"), 1)
3351
3352 def test_slash_star_scans_folder(self):
3353 """Test that folder/* scans folder/"""
3354 # This behaviour is a bit ambiguous - either include or scan could be
3355 # argued as most appropriate here, but only an empty folder is at stake
3356 # so long as test_slash_star_includes_folder_contents passes.
3357- self.assertEqual(inc_sel_dir("folder/*", "folder"), 2)
3358+ self.assertEqual(inc_sel_dir(u"folder/*", u"folder"), 2)
3359
3360 def test_slash_star_includes_folder_contents(self):
3361 """Test that folder/* includes folder contents"""
3362- self.assertEqual(inc_sel_file("folder/*", "folder/file.txt"), 1)
3363- self.assertEqual(inc_sel_file("folder/*", "folder/other_file.log"), 1)
3364+ self.assertEqual(inc_sel_file(u"folder/*", u"folder/file.txt"), 1)
3365+ self.assertEqual(inc_sel_file(u"folder/*", u"folder/other_file.log"), 1)
3366
3367 def test_slash_star_star_scans_folder(self):
3368 """Test that folder/** scans folder/"""
3369- self.assertEqual(inc_sel_dir("folder/**", "folder"), 2)
3370+ self.assertEqual(inc_sel_dir(u"folder/**", u"folder"), 2)
3371
3372 def test_simple_trailing_slash_match(self):
3373 """Test that a normal folder string ending in / matches that path"""
3374- self.assertEqual(inc_sel_dir("testfiles/select/1/2/1/",
3375- "testfiles/select/1/2/1"), 1)
3376+ self.assertEqual(inc_sel_dir(u"testfiles/select/1/2/1/",
3377+ u"testfiles/select/1/2/1"), 1)
3378
3379 def test_double_asterisk_string_slash(self):
3380 """Test string starting with ** and ending in /"""
3381- self.assertEqual(inc_sel_dir("**/1/2/", "testfiles/select/1/2"), 1)
3382+ self.assertEqual(inc_sel_dir(u"**/1/2/", u"testfiles/select/1/2"), 1)
3383
3384 def test_string_double_asterisk_string_slash(self):
3385 """Test string ** string /"""
3386- self.assertEqual(inc_sel_dir("testfiles**/2/",
3387- "testfiles/select/1/2"), 1)
3388+ self.assertEqual(inc_sel_dir(u"testfiles**/2/",
3389+ u"testfiles/select/1/2"), 1)
3390
3391
3392 class TestDoubleAsterisk(UnitTestCase):
3393@@ -211,19 +214,75 @@
3394
3395 def test_double_asterisk_no_match(self):
3396 """Test that a folder string ending /** does not match other paths"""
3397- self.assertEqual(inc_sel_dir("/test/folder/**", "/test/foo"), None)
3398+ self.assertEqual(inc_sel_dir(u"/test/folder/**", u"/test/foo"), None)
3399
3400 def test_double_asterisk_match(self):
3401 """Test that a folder string ending in /** matches that path"""
3402- self.assertEqual(inc_sel_dir("/test/folder/**",
3403- "/test/folder/foo"), 1)
3404- self.assertEqual(inc_sel_file("/test/folder/**",
3405- "/test/folder/foo.txt"), 1)
3406- self.assertEqual(inc_sel_dir("/test/folder/**",
3407- "/test/folder/2/foo"), 1)
3408- self.assertEqual(inc_sel_file("/test/folder/**",
3409- "/test/folder/2/foo.txt"), 1)
3410+ self.assertEqual(inc_sel_dir(u"/test/folder/**",
3411+ u"/test/folder/foo"), 1)
3412+ self.assertEqual(inc_sel_file(u"/test/folder/**",
3413+ u"/test/folder/foo.txt"), 1)
3414+ self.assertEqual(inc_sel_dir(u"/test/folder/**",
3415+ u"/test/folder/2/foo"), 1)
3416+ self.assertEqual(inc_sel_file(u"/test/folder/**",
3417+ u"/test/folder/2/foo.txt"), 1)
3418
3419 def test_asterisk_slash_double_asterisk(self):
3420 """Test folder string ending in */**"""
3421- self.assertEqual(inc_sel_dir("fold*/**", "folder"), 2)
3422+ self.assertEqual(inc_sel_dir(u"fold*/**", u"folder"), 2)
3423+
3424+
3425+class TestSimpleUnicode(UnitTestCase):
3426+ """Test simple unicode comparison"""
3427+
3428+ def test_simple_unicode(self):
3429+ """Test simple unicode comparison"""
3430+ self.assertEqual(inc_sel_file(u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt",
3431+ u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt"), 1)
3432+
3433+
3434+class TestSquareBrackets(UnitTestCase):
3435+ """Test glob matching where the glob includes []s and [!]s"""
3436+
3437+ def test_square_bracket_options(self):
3438+ """Test file including options in []s"""
3439+ self.assertEqual(inc_sel_file(u"/test/f[o,s,p]lder/foo.txt",
3440+ u"/test/folder/foo.txt"), 1)
3441+ self.assertEqual(inc_sel_file(u"/test/f[i,s,p]lder/foo.txt",
3442+ u"/test/folder/foo.txt"), None)
3443+ self.assertEqual(inc_sel_file(u"/test/f[s,o,p]lder/foo.txt",
3444+ u"/test/folder/foo.txt"), 1)
3445+
3446+ def test_square_bracket_options_unicode(self):
3447+ """Test file including options in []s"""
3448+ self.assertEqual(inc_sel_file(u"прыклад/пр[и,j,l]мер/例/Παράδειγμα/उदाहरण.txt",
3449+ u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt"), 1)
3450+ self.assertEqual(inc_sel_file(u"прыклад/п[a,b,c]имер/例/Παράδειγμα/उदाहरण.txt",
3451+ u"прыклад/пример/例/Παράδειγμα/उदाहरण.txt"), None)
3452+
3453+ def test_not_square_bracket_options(self):
3454+ """Test file including options in [!]s"""
3455+ self.assertEqual(inc_sel_file(u"/test/f[!o,s,p]lder/foo.txt",
3456+ u"/test/folder/foo.txt"), None)
3457+ self.assertEqual(inc_sel_file(u"/test/f[!i,s,p]lder/foo.txt",
3458+ u"/test/folder/foo.txt"), 1)
3459+ self.assertEqual(inc_sel_file(u"/test/f[!s,o,p]lder/foo.txt",
3460+ u"/test/folder/foo.txt"), None)
3461+
3462+ def test_square_bracket_range(self):
3463+ """Test file including range in []s"""
3464+ self.assertEqual(inc_sel_file(u"/test/folder[1-5]/foo.txt",
3465+ u"/test/folder4/foo.txt"), 1)
3466+ self.assertEqual(inc_sel_file(u"/test/folder[5-9]/foo.txt",
3467+ u"/test/folder4/foo.txt"), None)
3468+ self.assertEqual(inc_sel_file(u"/test/folder[1-5]/foo.txt",
3469+ u"/test/folder6/foo.txt"), None)
3470+
3471+ def test_square_bracket_not_range(self):
3472+ """Test file including range in [!]s"""
3473+ self.assertEqual(inc_sel_file(u"/test/folder[!1-5]/foo.txt",
3474+ u"/test/folder4/foo.txt"), None)
3475+ self.assertEqual(inc_sel_file(u"/test/folder[!5-9]/foo.txt",
3476+ u"/test/folder4/foo.txt"), 1)
3477+ self.assertEqual(inc_sel_file(u"/test/folder[!1-5]/foo.txt",
3478+ u"/test/folder6/foo.txt"), 1)
3479
3480=== modified file 'testing/unit/test_gpg.py'
3481--- testing/unit/test_gpg.py 2017-07-11 14:55:38 +0000
3482+++ testing/unit/test_gpg.py 2017-12-01 23:01:42 +0000
3483@@ -71,23 +71,23 @@
3484
3485 def test_gpg_asym(self):
3486 """Test GPG asymmetric encryption"""
3487- profile = gpg.GPGProfile(passphrase=self.sign_passphrase,
3488+ profile = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3489 recipients=[self.encrypt_key1,
3490 self.encrypt_key2])
3491 self.gpg_cycle("aoensutha aonetuh saoe", profile)
3492
3493- profile2 = gpg.GPGProfile(passphrase=self.sign_passphrase,
3494+ profile2 = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3495 recipients=[self.encrypt_key1])
3496 self.gpg_cycle("aoeu" * 10000, profile2)
3497
3498 def test_gpg_hidden_asym(self):
3499 """Test GPG asymmetric encryption with hidden key id"""
3500- profile = gpg.GPGProfile(passphrase=self.sign_passphrase,
3501+ profile = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3502 hidden_recipients=[self.encrypt_key1,
3503 self.encrypt_key2])
3504 self.gpg_cycle("aoensutha aonetuh saoe", profile)
3505
3506- profile2 = gpg.GPGProfile(passphrase=self.sign_passphrase,
3507+ profile2 = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3508 hidden_recipients=[self.encrypt_key1])
3509 self.gpg_cycle("aoeu" * 10000, profile2)
3510
3511@@ -95,7 +95,7 @@
3512 """Test to make sure GPG reports the proper signature key"""
3513 plaintext = "hello" * 50000
3514
3515- signing_profile = gpg.GPGProfile(passphrase=self.sign_passphrase,
3516+ signing_profile = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3517 sign_key=self.sign_key,
3518 recipients=[self.encrypt_key1])
3519
3520@@ -114,7 +114,7 @@
3521 """Test to make sure GPG reports the proper signature key even with hidden encryption key id"""
3522 plaintext = "hello" * 50000
3523
3524- signing_profile = gpg.GPGProfile(passphrase=self.sign_passphrase,
3525+ signing_profile = gpg.GPGProfile(passphrase=self.sign_passphrase_bytes,
3526 sign_key=self.sign_key,
3527 hidden_recipients=[self.encrypt_key1])
3528
3529
3530=== modified file 'testing/unit/test_patchdir.py'
3531--- testing/unit/test_patchdir.py 2015-02-01 17:37:37 +0000
3532+++ testing/unit/test_patchdir.py 2017-12-01 23:01:42 +0000
3533@@ -21,7 +21,6 @@
3534
3535 from future_builtins import map
3536
3537-import sys
3538 import cStringIO
3539 import unittest
3540
3541
3542=== modified file 'testing/unit/test_selection.py'
3543--- testing/unit/test_selection.py 2017-07-11 14:55:38 +0000
3544+++ testing/unit/test_selection.py 2017-12-01 23:01:42 +0000
3545@@ -1,3 +1,4 @@
3546+# -*- coding: utf-8 -*-
3547 # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
3548 #
3549 # Copyright 2002 Ben Escoto <ben@emerose.org>
3550@@ -36,165 +37,165 @@
3551 def setUp(self):
3552 super(MatchingTest, self).setUp()
3553 self.unpack_testfiles()
3554- self.root = Path("testfiles/select")
3555+ self.root = Path(u"testfiles/select")
3556 self.Select = Select(self.root)
3557
3558 def makeext(self, path):
3559- return self.root.new_index(tuple(path.split("/")))
3560+ return self.root.new_index(tuple(path.split(u"/")))
3561
3562 def testRegexp(self):
3563 """Test regular expression selection func"""
3564- sf1 = self.Select.regexp_get_sf(".*\.py", 1)
3565- assert sf1(self.makeext("1.py")) == 1
3566- assert sf1(self.makeext("usr/foo.py")) == 1
3567- assert sf1(self.root.append("1.doc")) is None
3568+ sf1 = self.Select.regexp_get_sf(u".*\.py", 1)
3569+ assert sf1(self.makeext(u"1.py")) == 1
3570+ assert sf1(self.makeext(u"usr/foo.py")) == 1
3571+ assert sf1(self.root.append(u"1.doc")) is None
3572
3573- sf2 = self.Select.regexp_get_sf("hello", 0)
3574- assert sf2(Path("hello")) == 0
3575- assert sf2(Path("foohello_there")) == 0
3576- assert sf2(Path("foo")) is None
3577+ sf2 = self.Select.regexp_get_sf(u"hello", 0)
3578+ assert sf2(Path(u"hello")) == 0
3579+ assert sf2(Path(u"foohello_there")) == 0
3580+ assert sf2(Path(u"foo")) is None
3581
3582 def test_tuple_include(self):
3583 """Test include selection function made from a regular filename"""
3584 self.assertRaises(FilePrefixError, self.Select.glob_get_normal_sf,
3585- "foo", 1)
3586-
3587- sf2 = self.Select.glob_get_sf("testfiles/select/usr/local/bin/", 1)
3588-
3589- with patch('duplicity.path.ROPath.isdir') as mock_isdir:
3590+ u"foo", 1)
3591+
3592+ sf2 = self.Select.glob_get_sf(u"testfiles/select/usr/local/bin/", 1)
3593+
3594+ with patch(u"duplicity.path.ROPath.isdir") as mock_isdir:
3595 mock_isdir.return_value = True
3596 # Can't pass the return_value as an argument to patch, i.e.:
3597- # with patch('duplicity.path.ROPath.isdir', return_value=True):
3598+ # with patch("duplicity.path.ROPath.isdir", return_value=True):
3599 # as build system's mock is too old to support it.
3600
3601- self.assertEqual(sf2(self.makeext("usr")), 2)
3602- self.assertEqual(sf2(self.makeext("usr/local")), 2)
3603- self.assertEqual(sf2(self.makeext("usr/local/bin")), 1)
3604- self.assertEqual(sf2(self.makeext("usr/local/doc")), None)
3605- self.assertEqual(sf2(self.makeext("usr/local/bin/gzip")), 1)
3606- self.assertEqual(sf2(self.makeext("usr/local/bingzip")), None)
3607+ self.assertEqual(sf2(self.makeext(u"usr")), 2)
3608+ self.assertEqual(sf2(self.makeext(u"usr/local")), 2)
3609+ self.assertEqual(sf2(self.makeext(u"usr/local/bin")), 1)
3610+ self.assertEqual(sf2(self.makeext(u"usr/local/doc")), None)
3611+ self.assertEqual(sf2(self.makeext(u"usr/local/bin/gzip")), 1)
3612+ self.assertEqual(sf2(self.makeext(u"usr/local/bingzip")), None)
3613
3614 def test_tuple_exclude(self):
3615 """Test exclude selection function made from a regular filename"""
3616 self.assertRaises(FilePrefixError, self.Select.glob_get_normal_sf,
3617- "foo", 0)
3618-
3619- sf2 = self.Select.glob_get_sf("testfiles/select/usr/local/bin/", 0)
3620-
3621- with patch('duplicity.path.ROPath.isdir') as mock_isdir:
3622+ u"foo", 0)
3623+
3624+ sf2 = self.Select.glob_get_sf(u"testfiles/select/usr/local/bin/", 0)
3625+
3626+ with patch(u"duplicity.path.ROPath.isdir") as mock_isdir:
3627 mock_isdir.return_value = True
3628
3629- assert sf2(self.makeext("usr")) is None
3630- assert sf2(self.makeext("usr/local")) is None
3631- assert sf2(self.makeext("usr/local/bin")) == 0
3632- assert sf2(self.makeext("usr/local/doc")) is None
3633- assert sf2(self.makeext("usr/local/bin/gzip")) == 0
3634- assert sf2(self.makeext("usr/local/bingzip")) is None
3635+ assert sf2(self.makeext(u"usr")) is None
3636+ assert sf2(self.makeext(u"usr/local")) is None
3637+ assert sf2(self.makeext(u"usr/local/bin")) == 0
3638+ assert sf2(self.makeext(u"usr/local/doc")) is None
3639+ assert sf2(self.makeext(u"usr/local/bin/gzip")) == 0
3640+ assert sf2(self.makeext(u"usr/local/bingzip")) is None
3641
3642 def test_glob_star_include(self):
3643 """Test a few globbing patterns, including **"""
3644- sf1 = self.Select.glob_get_sf("**", 1)
3645- assert sf1(self.makeext("foo")) == 1
3646- assert sf1(self.makeext("")) == 1
3647+ sf1 = self.Select.glob_get_sf(u"**", 1)
3648+ assert sf1(self.makeext(u"foo")) == 1
3649+ assert sf1(self.makeext(u"")) == 1
3650
3651- sf2 = self.Select.glob_get_sf("**.py", 1)
3652- assert sf2(self.makeext("foo")) == 2
3653- assert sf2(self.makeext("usr/local/bin")) == 2
3654- assert sf2(self.makeext("what/ever.py")) == 1
3655- assert sf2(self.makeext("what/ever.py/foo")) == 1
3656+ sf2 = self.Select.glob_get_sf(u"**.py", 1)
3657+ assert sf2(self.makeext(u"foo")) == 2
3658+ assert sf2(self.makeext(u"usr/local/bin")) == 2
3659+ assert sf2(self.makeext(u"what/ever.py")) == 1
3660+ assert sf2(self.makeext(u"what/ever.py/foo")) == 1
3661
3662 def test_glob_star_exclude(self):
3663 """Test a few glob excludes, including **"""
3664- sf1 = self.Select.glob_get_sf("**", 0)
3665- assert sf1(self.makeext("/usr/local/bin")) == 0
3666+ sf1 = self.Select.glob_get_sf(u"**", 0)
3667+ assert sf1(self.makeext(u"/usr/local/bin")) == 0
3668
3669- sf2 = self.Select.glob_get_sf("**.py", 0)
3670- assert sf2(self.makeext("foo")) is None
3671- assert sf2(self.makeext("usr/local/bin")) is None
3672- assert sf2(self.makeext("what/ever.py")) == 0
3673- assert sf2(self.makeext("what/ever.py/foo")) == 0
3674+ sf2 = self.Select.glob_get_sf(u"**.py", 0)
3675+ assert sf2(self.makeext(u"foo")) is None
3676+ assert sf2(self.makeext(u"usr/local/bin")) is None
3677+ assert sf2(self.makeext(u"what/ever.py")) == 0
3678+ assert sf2(self.makeext(u"what/ever.py/foo")) == 0
3679
3680 def test_simple_glob_double_asterisk(self):
3681 """test_simple_glob_double_asterisk - primarily to check that the defaults used by the error tests work"""
3682- assert self.Select.glob_get_normal_sf("**", 1)
3683+ assert self.Select.glob_get_normal_sf(u"**", 1)
3684
3685 def test_glob_sf_exception(self):
3686 """test_glob_sf_exception - see if globbing errors returned"""
3687 self.assertRaises(GlobbingError, self.Select.glob_get_normal_sf,
3688- "testfiles/select/hello//there", 1)
3689+ u"testfiles/select/hello//there", 1)
3690
3691 def test_file_prefix_sf_exception(self):
3692 """test_file_prefix_sf_exception - see if FilePrefix error is returned"""
3693 # These should raise a FilePrefixError because the root directory for the selection is "testfiles/select"
3694 self.assertRaises(FilePrefixError,
3695- self.Select.glob_get_sf, "testfiles/whatever", 1)
3696+ self.Select.glob_get_sf, u"testfiles/whatever", 1)
3697 self.assertRaises(FilePrefixError,
3698- self.Select.glob_get_sf, "testfiles/?hello", 0)
3699+ self.Select.glob_get_sf, u"testfiles/?hello", 0)
3700
3701 def test_scan(self):
3702 """Tests what is returned for selection tests regarding directory scanning"""
3703- select = Select(Path("/"))
3704+ select = Select(Path(u"/"))
3705
3706- assert select.glob_get_sf("**.py", 1)(Path("/")) == 2
3707- assert select.glob_get_sf("**.py", 1)(Path("foo")) == 2
3708- assert select.glob_get_sf("**.py", 1)(Path("usr/local/bin")) == 2
3709- assert select.glob_get_sf("/testfiles/select/**.py", 1)(Path("/testfiles/select")) == 2
3710- assert select.glob_get_sf("/testfiles/select/test.py", 1)(Path("/testfiles/select")) == 2
3711- assert select.glob_get_normal_sf("/testfiles/se?ect/test.py", 1)(Path("/testfiles/select")) == 2
3712- assert select.glob_get_sf("/testfiles/select/test.py", 0)(Path("/testfiles/select")) is None
3713- assert select.glob_get_normal_sf("/testfiles/select/test.py", 0)(Path("/testfiles/select")) is None
3714+ assert select.glob_get_sf(u"**.py", 1)(Path(u"/")) == 2
3715+ assert select.glob_get_sf(u"**.py", 1)(Path(u"foo")) == 2
3716+ assert select.glob_get_sf(u"**.py", 1)(Path(u"usr/local/bin")) == 2
3717+ assert select.glob_get_sf(u"/testfiles/select/**.py", 1)(Path(u"/testfiles/select")) == 2
3718+ assert select.glob_get_sf(u"/testfiles/select/test.py", 1)(Path(u"/testfiles/select")) == 2
3719+ assert select.glob_get_normal_sf(u"/testfiles/se?ect/test.py", 1)(Path(u"/testfiles/select")) == 2
3720+ assert select.glob_get_sf(u"/testfiles/select/test.py", 0)(Path(u"/testfiles/select")) is None
3721+ assert select.glob_get_normal_sf(u"/testfiles/select/test.py", 0)(Path(u"/testfiles/select")) is None
3722
3723 def test_ignore_case(self):
3724 """test_ignore_case - try a few expressions with ignorecase:"""
3725
3726- sf = self.Select.glob_get_sf("ignorecase:testfiles/SeLect/foo/bar", 1)
3727- assert sf(self.makeext("FOO/BAR")) == 1
3728- assert sf(self.makeext("foo/bar")) == 1
3729- assert sf(self.makeext("fOo/BaR")) == 1
3730- self.assertRaises(FilePrefixError, self.Select.glob_get_sf, "ignorecase:tesfiles/sect/foo/bar", 1)
3731+ sf = self.Select.glob_get_sf(u"ignorecase:testfiles/SeLect/foo/bar", 1)
3732+ assert sf(self.makeext(u"FOO/BAR")) == 1
3733+ assert sf(self.makeext(u"foo/bar")) == 1
3734+ assert sf(self.makeext(u"fOo/BaR")) == 1
3735+ self.assertRaises(FilePrefixError, self.Select.glob_get_sf, u"ignorecase:tesfiles/sect/foo/bar", 1)
3736
3737 def test_root(self):
3738 """test_root - / may be a counterexample to several of these.."""
3739- root = Path("/")
3740+ root = Path(u"/")
3741 select = Select(root)
3742
3743- self.assertEqual(select.glob_get_sf("/", 1)(root), 1)
3744- self.assertEqual(select.glob_get_sf("/foo", 1)(root), 2)
3745- self.assertEqual(select.glob_get_sf("/foo/bar", 1)(root), 2)
3746- self.assertEqual(select.glob_get_sf("/", 0)(root), 0)
3747- self.assertEqual(select.glob_get_sf("/foo", 0)(root), None)
3748+ self.assertEqual(select.glob_get_sf(u"/", 1)(root), 1)
3749+ self.assertEqual(select.glob_get_sf(u"/foo", 1)(root), 2)
3750+ self.assertEqual(select.glob_get_sf(u"/foo/bar", 1)(root), 2)
3751+ self.assertEqual(select.glob_get_sf(u"/", 0)(root), 0)
3752+ self.assertEqual(select.glob_get_sf(u"/foo", 0)(root), None)
3753
3754- assert select.glob_get_sf("**.py", 1)(root) == 2
3755- assert select.glob_get_sf("**", 1)(root) == 1
3756- assert select.glob_get_sf("ignorecase:/", 1)(root) == 1
3757- assert select.glob_get_sf("**.py", 0)(root) is None
3758- assert select.glob_get_sf("**", 0)(root) == 0
3759- assert select.glob_get_sf("/foo/*", 0)(root) is None
3760+ assert select.glob_get_sf(u"**.py", 1)(root) == 2
3761+ assert select.glob_get_sf(u"**", 1)(root) == 1
3762+ assert select.glob_get_sf(u"ignorecase:/", 1)(root) == 1
3763+ assert select.glob_get_sf(u"**.py", 0)(root) is None
3764+ assert select.glob_get_sf(u"**", 0)(root) == 0
3765+ assert select.glob_get_sf(u"/foo/*", 0)(root) is None
3766
3767 def test_other_filesystems(self):
3768 """Test to see if --exclude-other-filesystems works correctly"""
3769- root = Path("/")
3770+ root = Path(u"/")
3771 select = Select(root)
3772 sf = select.other_filesystems_get_sf(0)
3773 assert sf(root) is None
3774- if os.path.ismount("/usr/bin"):
3775- sfval = 0
3776- else:
3777- sfval = None
3778- assert sf(Path("/usr/bin")) == sfval, \
3779- "Assumption: /usr/bin is on the same filesystem as /"
3780- if os.path.ismount("/dev"):
3781- sfval = 0
3782- else:
3783- sfval = None
3784- assert sf(Path("/dev")) == sfval, \
3785- "Assumption: /dev is on a different filesystem"
3786- if os.path.ismount("/proc"):
3787- sfval = 0
3788- else:
3789- sfval = None
3790- assert sf(Path("/proc")) == sfval, \
3791- "Assumption: /proc is on a different filesystem"
3792+ if os.path.ismount(u"/usr/bin"):
3793+ sfval = 0
3794+ else:
3795+ sfval = None
3796+ assert sf(Path(u"/usr/bin")) == sfval, \
3797+ u"Assumption: /usr/bin is on the same filesystem as /"
3798+ if os.path.ismount(u"/dev"):
3799+ sfval = 0
3800+ else:
3801+ sfval = None
3802+ assert sf(Path(u"/dev")) == sfval, \
3803+ u"Assumption: /dev is on a different filesystem"
3804+ if os.path.ismount(u"/proc"):
3805+ sfval = 0
3806+ else:
3807+ sfval = None
3808+ assert sf(Path(u"/proc")) == sfval, \
3809+ u"Assumption: /proc is on a different filesystem"
3810
3811
3812 class ParseArgsTest(UnitTestCase):
3813@@ -203,24 +204,34 @@
3814 super(ParseArgsTest, self).setUp()
3815 self.unpack_testfiles()
3816 self.root = None
3817- self.expected_restored_tree = [(), ('1',), ('1', '1sub1'), ('1', '1sub1', '1sub1sub1'),
3818- ('1', '1sub1', '1sub1sub1', '1sub1sub1_file.txt'), ('1', '1sub1', '1sub1sub3'),
3819- ('1', '1sub2'), ('1', '1sub2', '1sub2sub1'), ('1', '1sub3'),
3820- ('1', '1sub3', '1sub3sub3'), ('1.py',), ('2',), ('2', '2sub1'),
3821- ('2', '2sub1', '2sub1sub1'), ('2', '2sub1', '2sub1sub1', '2sub1sub1_file.txt'),
3822- ('3',), ('3', '3sub2'), ('3', '3sub2', '3sub2sub1'),
3823- ('3', '3sub2', '3sub2sub2'), ('3', '3sub2', '3sub2sub3'), ('3', '3sub3'),
3824- ('3', '3sub3', '3sub3sub1'), ('3', '3sub3', '3sub3sub2'),
3825- ('3', '3sub3', '3sub3sub2', '3sub3sub2_file.txt'), ('3', '3sub3', '3sub3sub3')]
3826+ self.expected_restored_tree = [(), (u"1",), (u"1", u"1sub1"), (u"1", u"1sub1", u"1sub1sub1"),
3827+ (u"1", u"1sub1", u"1sub1sub1", u"1sub1sub1_file.txt"),
3828+ (u"1", u"1sub1", u"1sub1sub3"), (u"1", u"1sub2"), (u"1", u"1sub2", u"1sub2sub1"),
3829+ (u"1", u"1sub3"), (u"1", u"1sub3", u"1sub3sub3"), (u"1.py",), (u"2",),
3830+ (u"2", u"2sub1"), (u"2", u"2sub1", u"2sub1sub1"),
3831+ (u"2", u"2sub1", u"2sub1sub1", u"2sub1sub1_file.txt"),
3832+ (u"3",), (u"3", u"3sub2"), (u"3", u"3sub2", u"3sub2sub1"),
3833+ (u"3", u"3sub2", u"3sub2sub2"), (u"3", u"3sub2", u"3sub2sub3"), (u"3", u"3sub3"),
3834+ (u"3", u"3sub3", u"3sub3sub1"), (u"3", u"3sub3", u"3sub3sub2"),
3835+ (u"3", u"3sub3", u"3sub3sub2", u"3sub3sub2_file.txt"),
3836+ (u"3", u"3sub3", u"3sub3sub3")]
3837+
3838+ def uc_index_from_path(self, path):
3839+ """Takes a path type and returns path.index, with each element converted into unicode"""
3840+ uindex = tuple([element.decode(sys.getfilesystemencoding(), "strict") for element in path.index])
3841+ return uindex
3842
3843 def ParseTest(self, tuplelist, indicies, filelists=[]):
3844 """No error if running select on tuple goes over indicies"""
3845 if not self.root:
3846- self.root = Path("testfiles/select")
3847+ self.root = Path(u"testfiles/select")
3848 self.Select = Select(self.root)
3849 self.Select.ParseArgs(tuplelist, self.remake_filelists(filelists))
3850 self.Select.set_iter()
3851- results_as_list = list(Iter.map(lambda path: path.index, self.Select))
3852+
3853+ # Create a list of the paths returned by the select function, converted
3854+ # into path.index styled tuples
3855+ results_as_list = list(Iter.map(self.uc_index_from_path, self.Select))
3856 # print(results_as_list)
3857 self.assertEqual(indicies, results_as_list)
3858
3859@@ -228,7 +239,7 @@
3860 """Turn strings in filelist into fileobjs"""
3861 new_filelists = []
3862 for f in filelist:
3863- if isinstance(f, types.StringType):
3864+ if isinstance(f, unicode):
3865 new_filelists.append(StringIO.StringIO(f))
3866 else:
3867 new_filelists.append(f)
3868@@ -236,629 +247,645 @@
3869
3870 def test_parse(self):
3871 """Test just one include, all exclude"""
3872- self.ParseTest([("--include", "testfiles/select/1/1"),
3873- ("--exclude", "**")],
3874- [(), ('1',), ("1", "1"), ("1", '1', '1'),
3875- ('1', '1', '2'), ('1', '1', '3')])
3876+ self.ParseTest([(u"--include", u"testfiles/select/1/1"),
3877+ (u"--exclude", u"**")],
3878+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"1"),
3879+ (u"1", u"1", u"2"), (u"1", u"1", u"3")])
3880
3881 def test_parse2(self):
3882 """Test three level include/exclude"""
3883- self.ParseTest([("--exclude", "testfiles/select/1/1/1"),
3884- ("--include", "testfiles/select/1/1"),
3885- ("--exclude", "testfiles/select/1"),
3886- ("--exclude", "**")],
3887- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3888- ('1', '1', '3')])
3889+ self.ParseTest([(u"--exclude", u"testfiles/select/1/1/1"),
3890+ (u"--include", u"testfiles/select/1/1"),
3891+ (u"--exclude", u"testfiles/select/1"),
3892+ (u"--exclude", u"**")],
3893+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3894+ (u"1", u"1", u"3")])
3895
3896 def test_filelist(self):
3897 """Filelist glob test similar to above testParse2"""
3898- self.ParseTest([("--include-filelist", "file")],
3899- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3900- ('1', '1', '3')],
3901- ["- testfiles/select/1/1/1\n"
3902- "testfiles/select/1/1\n"
3903- "- testfiles/select/1\n"
3904- "- **"])
3905+ self.ParseTest([(u"--include-filelist", u"file")],
3906+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3907+ (u"1", u"1", u"3")],
3908+ [u"- testfiles/select/1/1/1\n"
3909+ u"testfiles/select/1/1\n"
3910+ u"- testfiles/select/1\n"
3911+ u"- **"])
3912
3913 def test_include_filelist_1_trailing_whitespace(self):
3914 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on include"""
3915- self.ParseTest([("--include-filelist", "file")],
3916- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3917- ('1', '1', '3')],
3918- ["- testfiles/select/1/1/1\n"
3919- "testfiles/select/1/1 \n"
3920- "- testfiles/select/1\n"
3921- "- **"])
3922+ self.ParseTest([(u"--include-filelist", u"file")],
3923+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3924+ (u"1", u"1", u"3")],
3925+ [u"- testfiles/select/1/1/1\n"
3926+ u"testfiles/select/1/1 \n"
3927+ u"- testfiles/select/1\n"
3928+ u"- **"])
3929
3930 def test_include_filelist_2_trailing_whitespaces(self):
3931 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on include"""
3932- self.ParseTest([("--include-filelist", "file")],
3933- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3934- ('1', '1', '3')],
3935- ["- testfiles/select/1/1/1\n"
3936- "testfiles/select/1/1 \n"
3937- "- testfiles/select/1\n"
3938- "- **"])
3939+ self.ParseTest([(u"--include-filelist", u"file")],
3940+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3941+ (u"1", u"1", u"3")],
3942+ [u"- testfiles/select/1/1/1\n"
3943+ u"testfiles/select/1/1 \n"
3944+ u"- testfiles/select/1\n"
3945+ u"- **"])
3946
3947 def test_include_filelist_1_leading_whitespace(self):
3948 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on include"""
3949- self.ParseTest([("--include-filelist", "file")],
3950- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3951- ('1', '1', '3')],
3952- ["- testfiles/select/1/1/1\n"
3953- " testfiles/select/1/1\n"
3954- "- testfiles/select/1\n"
3955- "- **"])
3956+ self.ParseTest([(u"--include-filelist", u"file")],
3957+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3958+ (u"1", u"1", u"3")],
3959+ [u"- testfiles/select/1/1/1\n"
3960+ u" testfiles/select/1/1\n"
3961+ u"- testfiles/select/1\n"
3962+ u"- **"])
3963
3964 def test_include_filelist_2_leading_whitespaces(self):
3965 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on include"""
3966- self.ParseTest([("--include-filelist", "file")],
3967- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3968- ('1', '1', '3')],
3969- ["- testfiles/select/1/1/1\n"
3970- " testfiles/select/1/1\n"
3971- "- testfiles/select/1\n"
3972- "- **"])
3973+ self.ParseTest([(u"--include-filelist", u"file")],
3974+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3975+ (u"1", u"1", u"3")],
3976+ [u"- testfiles/select/1/1/1\n"
3977+ u" testfiles/select/1/1\n"
3978+ u"- testfiles/select/1\n"
3979+ u"- **"])
3980
3981 def test_include_filelist_1_trailing_whitespace_exclude(self):
3982 """Filelist glob test similar to globbing filelist, but with 1 trailing whitespace on exclude"""
3983- self.ParseTest([("--include-filelist", "file")],
3984- [(), ('1',), ('1', '1'), ('1', '1', '2'),
3985- ('1', '1', '3')],
3986- ["- testfiles/select/1/1/1 \n"
3987- "testfiles/select/1/1\n"
3988- "- testfiles/select/1\n"
3989- "- **"])
3990+ self.ParseTest([(u"--include-filelist", u"file")],
3991+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
3992+ (u"1", u"1", u"3")],
3993+ [u"- testfiles/select/1/1/1 \n"
3994+ u"testfiles/select/1/1\n"
3995+ u"- testfiles/select/1\n"
3996+ u"- **"])
3997
3998 def test_include_filelist_2_trailing_whitespace_exclude(self):
3999 """Filelist glob test similar to globbing filelist, but with 2 trailing whitespaces on exclude"""
4000- self.ParseTest([("--include-filelist", "file")],
4001- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4002- ('1', '1', '3')],
4003- ["- testfiles/select/1/1/1 \n"
4004- "testfiles/select/1/1\n"
4005- "- testfiles/select/1\n"
4006- "- **"])
4007+ self.ParseTest([(u"--include-filelist", u"file")],
4008+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4009+ (u"1", u"1", u"3")],
4010+ [u"- testfiles/select/1/1/1 \n"
4011+ u"testfiles/select/1/1\n"
4012+ u"- testfiles/select/1\n"
4013+ u"- **"])
4014
4015 def test_include_filelist_1_leading_whitespace_exclude(self):
4016 """Filelist glob test similar to globbing filelist, but with 1 leading whitespace on exclude"""
4017- self.ParseTest([("--include-filelist", "file")],
4018- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4019- ('1', '1', '3')],
4020- [" - testfiles/select/1/1/1\n"
4021- "testfiles/select/1/1\n"
4022- "- testfiles/select/1\n"
4023- "- **"])
4024+ self.ParseTest([(u"--include-filelist", u"file")],
4025+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4026+ (u"1", u"1", u"3")],
4027+ [u" - testfiles/select/1/1/1\n"
4028+ u"testfiles/select/1/1\n"
4029+ u"- testfiles/select/1\n"
4030+ u"- **"])
4031
4032 def test_include_filelist_2_leading_whitespaces_exclude(self):
4033 """Filelist glob test similar to globbing filelist, but with 2 leading whitespaces on exclude"""
4034- self.ParseTest([("--include-filelist", "file")],
4035- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4036- ('1', '1', '3')],
4037- [" - testfiles/select/1/1/1\n"
4038- "testfiles/select/1/1\n"
4039- "- testfiles/select/1\n"
4040- "- **"])
4041+ self.ParseTest([(u"--include-filelist", u"file")],
4042+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4043+ (u"1", u"1", u"3")],
4044+ [u" - testfiles/select/1/1/1\n"
4045+ u"testfiles/select/1/1\n"
4046+ u"- testfiles/select/1\n"
4047+ u"- **"])
4048
4049 def test_include_filelist_check_excluded_folder_included_for_contents(self):
4050 """Filelist glob test to check excluded folder is included if contents are"""
4051- self.ParseTest([("--include-filelist", "file")],
4052- [(), ('1',), ('1', '1'), ('1', '1', '1'), ('1', '1', '2'),
4053- ('1', '1', '3'), ('1', '2'), ('1', '2', '1'), ('1', '3'), ('1', '3', '1'), ('1', '3', '2'),
4054- ('1', '3', '3')],
4055- ["+ testfiles/select/1/2/1\n"
4056- "- testfiles/select/1/2\n"
4057- "testfiles/select/1\n"
4058- "- **"])
4059+ self.ParseTest([(u"--include-filelist", u"file")],
4060+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"1"), (u"1", u"1", u"2"),
4061+ (u"1", u"1", u"3"), (u"1", u"2"), (u"1", u"2", u"1"), (u"1", u"3"), (u"1", u"3", u"1"),
4062+ (u"1", u"3", u"2"), (u"1", u"3", u"3")],
4063+ [u"+ testfiles/select/1/2/1\n"
4064+ u"- testfiles/select/1/2\n"
4065+ u"testfiles/select/1\n"
4066+ u"- **"])
4067
4068 def test_include_filelist_with_unnecessary_quotes(self):
4069 """Filelist glob test similar to globbing filelist, but with quotes around one of the paths."""
4070- self.ParseTest([("--include-filelist", "file")],
4071- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4072- ('1', '1', '3')],
4073- ["- 'testfiles/select/1/1/1'\n"
4074- "testfiles/select/1/1\n"
4075- "- testfiles/select/1\n"
4076- "- **"])
4077+ self.ParseTest([(u"--include-filelist", u"file")],
4078+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4079+ (u"1", u"1", u"3")],
4080+ [u"- 'testfiles/select/1/1/1'\n"
4081+ u"testfiles/select/1/1\n"
4082+ u"- testfiles/select/1\n"
4083+ u"- **"])
4084
4085 def test_include_filelist_with_unnecessary_double_quotes(self):
4086 """Filelist glob test similar to globbing filelist, but with double quotes around one of the paths."""
4087- self.ParseTest([("--include-filelist", "file")],
4088- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4089- ('1', '1', '3')],
4090- ['- "testfiles/select/1/1/1"\n'
4091- 'testfiles/select/1/1\n'
4092- '- testfiles/select/1\n'
4093- '- **'])
4094+ self.ParseTest([(u"--include-filelist", u"file")],
4095+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4096+ (u"1", u"1", u"3")],
4097+ [u'- "testfiles/select/1/1/1"\n'
4098+ u"testfiles/select/1/1\n"
4099+ u"- testfiles/select/1\n"
4100+ u"- **"])
4101
4102 def test_include_filelist_with_full_line_comment(self):
4103 """Filelist glob test similar to globbing filelist, but with a full-line comment."""
4104- self.ParseTest([("--include-filelist", "file")],
4105- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4106- ('1', '1', '3')],
4107- ['- testfiles/select/1/1/1\n'
4108- '# This is a test\n'
4109- 'testfiles/select/1/1\n'
4110- '- testfiles/select/1\n'
4111- '- **'])
4112+ self.ParseTest([(u"--include-filelist", u"file")],
4113+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4114+ (u"1", u"1", u"3")],
4115+ [u"- testfiles/select/1/1/1\n"
4116+ u"# This is a test\n"
4117+ u"testfiles/select/1/1\n"
4118+ u"- testfiles/select/1\n"
4119+ u"- **"])
4120
4121 def test_include_filelist_with_blank_line(self):
4122 """Filelist glob test similar to globbing filelist, but with a blank line."""
4123- self.ParseTest([("--include-filelist", "file")],
4124- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4125- ('1', '1', '3')],
4126- ['- testfiles/select/1/1/1\n'
4127- '\n'
4128- 'testfiles/select/1/1\n'
4129- '- testfiles/select/1\n'
4130- '- **'])
4131+ self.ParseTest([(u"--include-filelist", u"file")],
4132+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4133+ (u"1", u"1", u"3")],
4134+ [u"- testfiles/select/1/1/1\n"
4135+ u"\n"
4136+ u"testfiles/select/1/1\n"
4137+ u"- testfiles/select/1\n"
4138+ u"- **"])
4139
4140 def test_include_filelist_with_blank_line_and_whitespace(self):
4141 """Filelist glob test similar to globbing filelist, but with a blank line and whitespace."""
4142- self.ParseTest([("--include-filelist", "file")],
4143- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4144- ('1', '1', '3')],
4145- ['- testfiles/select/1/1/1\n'
4146- ' \n'
4147- 'testfiles/select/1/1\n'
4148- '- testfiles/select/1\n'
4149- '- **'])
4150+ self.ParseTest([(u"--include-filelist", u"file")],
4151+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4152+ (u"1", u"1", u"3")],
4153+ [u"- testfiles/select/1/1/1\n"
4154+ u" \n"
4155+ u"testfiles/select/1/1\n"
4156+ u"- testfiles/select/1\n"
4157+ u"- **"])
4158
4159 def test_include_filelist_asterisk(self):
4160 """Filelist glob test with * instead of 'testfiles'"""
4161 # Thank you to Elifarley Cruz for this test case
4162 # (https://bugs.launchpad.net/duplicity/+bug/884371).
4163- self.ParseTest([("--include-filelist", "file")],
4164- [(), ('1',), ('1', '1'), ('1', '1', '1'),
4165- ('1', '1', '2'), ('1', '1', '3')],
4166- ["*/select/1/1\n"
4167- "- **"])
4168+ self.ParseTest([(u"--include-filelist", u"file")],
4169+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"1"),
4170+ (u"1", u"1", u"2"), (u"1", u"1", u"3")],
4171+ [u"*/select/1/1\n"
4172+ u"- **"])
4173
4174 def test_include_filelist_asterisk_2(self):
4175- """Identical to test_filelist, but with the exclude 'select' replaced with '*'"""
4176- self.ParseTest([("--include-filelist", "file")],
4177- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4178- ('1', '1', '3')],
4179- ["- testfiles/*/1/1/1\n"
4180- "testfiles/select/1/1\n"
4181- "- testfiles/select/1\n"
4182- "- **"])
4183+ """Identical to test_filelist, but with the exclude "select" replaced with '*'"""
4184+ self.ParseTest([(u"--include-filelist", u"file")],
4185+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4186+ (u"1", u"1", u"3")],
4187+ [u"- testfiles/*/1/1/1\n"
4188+ u"testfiles/select/1/1\n"
4189+ u"- testfiles/select/1\n"
4190+ u"- **"])
4191
4192 def test_include_filelist_asterisk_3(self):
4193- """Identical to test_filelist, but with the auto-include 'select' replaced with '*'"""
4194+ """Identical to test_filelist, but with the auto-include "select" replaced with '*'"""
4195 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4196- self.ParseTest([("--include-filelist", "file")],
4197- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4198- ('1', '1', '3')],
4199- ["- testfiles/select/1/1/1\n"
4200- "testfiles/*/1/1\n"
4201- "- testfiles/select/1\n"
4202- "- **"])
4203+ self.ParseTest([(u"--include-filelist", u"file")],
4204+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4205+ (u"1", u"1", u"3")],
4206+ [u"- testfiles/select/1/1/1\n"
4207+ u"testfiles/*/1/1\n"
4208+ u"- testfiles/select/1\n"
4209+ u"- **"])
4210
4211 def test_include_filelist_asterisk_4(self):
4212- """Identical to test_filelist, but with a specific include 'select' replaced with '*'"""
4213+ """Identical to test_filelist, but with a specific include "select" replaced with '*'"""
4214 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4215- self.ParseTest([("--include-filelist", "file")],
4216- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4217- ('1', '1', '3')],
4218- ["- testfiles/select/1/1/1\n"
4219- "+ testfiles/*/1/1\n"
4220- "- testfiles/select/1\n"
4221- "- **"])
4222+ self.ParseTest([(u"--include-filelist", u"file")],
4223+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4224+ (u"1", u"1", u"3")],
4225+ [u"- testfiles/select/1/1/1\n"
4226+ u"+ testfiles/*/1/1\n"
4227+ u"- testfiles/select/1\n"
4228+ u"- **"])
4229
4230 def test_include_filelist_asterisk_5(self):
4231 """Identical to test_filelist, but with all 'select's replaced with '*'"""
4232 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4233- self.ParseTest([("--include-filelist", "file")],
4234- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4235- ('1', '1', '3')],
4236- ["- testfiles/*/1/1/1\n"
4237- "+ testfiles/*/1/1\n"
4238- "- testfiles/*/1\n"
4239- "- **"])
4240+ self.ParseTest([(u"--include-filelist", u"file")],
4241+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4242+ (u"1", u"1", u"3")],
4243+ [u"- testfiles/*/1/1/1\n"
4244+ u"+ testfiles/*/1/1\n"
4245+ u"- testfiles/*/1\n"
4246+ u"- **"])
4247
4248 def test_include_filelist_asterisk_6(self):
4249 """Identical to test_filelist, but with numerous excluded folders replaced with '*'"""
4250- self.ParseTest([("--include-filelist", "file")],
4251- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4252- ('1', '1', '3')],
4253- ["- */*/1/1/1\n"
4254- "+ testfiles/select/1/1\n"
4255- "- */*/1\n"
4256- "- **"])
4257+ self.ParseTest([(u"--include-filelist", u"file")],
4258+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4259+ (u"1", u"1", u"3")],
4260+ [u"- */*/1/1/1\n"
4261+ u"+ testfiles/select/1/1\n"
4262+ u"- */*/1\n"
4263+ u"- **"])
4264
4265 def test_include_filelist_asterisk_7(self):
4266 """Identical to test_filelist, but with numerous included/excluded folders replaced with '*'"""
4267 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4268- self.ParseTest([("--include-filelist", "file")],
4269- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4270- ('1', '1', '3')],
4271- ["- */*/1/1/1\n"
4272- "+ */*/1/1\n"
4273- "- */*/1\n"
4274- "- **"])
4275+ self.ParseTest([(u"--include-filelist", u"file")],
4276+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4277+ (u"1", u"1", u"3")],
4278+ [u"- */*/1/1/1\n"
4279+ u"+ */*/1/1\n"
4280+ u"- */*/1\n"
4281+ u"- **"])
4282
4283 def test_include_filelist_double_asterisk_1(self):
4284- """Identical to test_filelist, but with the exclude 'select' replaced with '**'"""
4285- self.ParseTest([("--include-filelist", "file")],
4286- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4287- ('1', '1', '3')],
4288- ["- testfiles/**/1/1/1\n"
4289- "testfiles/select/1/1\n"
4290- "- testfiles/select/1\n"
4291- "- **"])
4292+ """Identical to test_filelist, but with the exclude "select' replaced with '**'"""
4293+ self.ParseTest([(u"--include-filelist", u"file")],
4294+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4295+ (u"1", u"1", u"3")],
4296+ [u"- testfiles/**/1/1/1\n"
4297+ u"testfiles/select/1/1\n"
4298+ u"- testfiles/select/1\n"
4299+ u"- **"])
4300
4301 def test_include_filelist_double_asterisk_2(self):
4302 """Identical to test_filelist, but with the include 'select' replaced with '**'"""
4303 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4304- self.ParseTest([("--include-filelist", "file")],
4305- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4306- ('1', '1', '3')],
4307- ["- testfiles/select/1/1/1\n"
4308- "**ct/1/1\n"
4309- "- testfiles/select/1\n"
4310- "- **"])
4311+ self.ParseTest([(u"--include-filelist", u"file")],
4312+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4313+ (u"1", u"1", u"3")],
4314+ [u"- testfiles/select/1/1/1\n"
4315+ u"**ct/1/1\n"
4316+ u"- testfiles/select/1\n"
4317+ u"- **"])
4318
4319 def test_include_filelist_double_asterisk_3(self):
4320 """Identical to test_filelist, but with the exclude 'testfiles/select' replaced with '**'"""
4321- self.ParseTest([("--include-filelist", "file")],
4322- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4323- ('1', '1', '3')],
4324- ["- **/1/1/1\n"
4325- "testfiles/select/1/1\n"
4326- "- testfiles/select/1\n"
4327- "- **"])
4328+ self.ParseTest([(u"--include-filelist", u"file")],
4329+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4330+ (u"1", u"1", u"3")],
4331+ [u"- **/1/1/1\n"
4332+ u"testfiles/select/1/1\n"
4333+ u"- testfiles/select/1\n"
4334+ u"- **"])
4335
4336 def test_include_filelist_double_asterisk_4(self):
4337 """Identical to test_filelist, but with the include 'testfiles/select' replaced with '**'"""
4338 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4339- self.ParseTest([("--include-filelist", "file")],
4340- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4341- ('1', '1', '3')],
4342- ["- testfiles/select/1/1/1\n"
4343- "**t/1/1\n"
4344- "- testfiles/select/1\n"
4345- "- **"])
4346+ self.ParseTest([(u"--include-filelist", u"file")],
4347+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4348+ (u"1", u"1", u"3")],
4349+ [u"- testfiles/select/1/1/1\n"
4350+ u"**t/1/1\n"
4351+ u"- testfiles/select/1\n"
4352+ u"- **"])
4353
4354 def test_include_filelist_double_asterisk_5(self):
4355 """Identical to test_filelist, but with all 'testfiles/select's replaced with '**'"""
4356 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4357- self.ParseTest([("--include-filelist", "file")],
4358- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4359- ('1', '1', '3')],
4360- ["- **/1/1/1\n"
4361- "**t/1/1\n"
4362- "- **t/1\n"
4363- "- **"])
4364+ self.ParseTest([(u"--include-filelist", u"file")],
4365+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4366+ (u"1", u"1", u"3")],
4367+ [u"- **/1/1/1\n"
4368+ u"**t/1/1\n"
4369+ u"- **t/1\n"
4370+ u"- **"])
4371
4372 def test_include_filelist_trailing_slashes(self):
4373 """Filelist glob test similar to globbing filelist, but with trailing slashes"""
4374- self.ParseTest([("--include-filelist", "file")],
4375- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4376- ('1', '1', '3')],
4377- ["- testfiles/select/1/1/1/\n"
4378- "testfiles/select/1/1/\n"
4379- "- testfiles/select/1/\n"
4380- "- **"])
4381+ self.ParseTest([(u"--include-filelist", u"file")],
4382+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4383+ (u"1", u"1", u"3")],
4384+ [u"- testfiles/select/1/1/1/\n"
4385+ u"testfiles/select/1/1/\n"
4386+ u"- testfiles/select/1/\n"
4387+ u"- **"])
4388
4389 def test_include_filelist_trailing_slashes_and_single_asterisks(self):
4390 """Filelist glob test similar to globbing filelist, but with trailing slashes and single asterisks"""
4391 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
4392- self.ParseTest([("--include-filelist", "file")],
4393- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4394- ('1', '1', '3')],
4395- ["- */select/1/1/1/\n"
4396- "testfiles/select/1/1/\n"
4397- "- testfiles/*/1/\n"
4398- "- **"])
4399+ self.ParseTest([(u"--include-filelist", u"file")],
4400+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4401+ (u"1", u"1", u"3")],
4402+ [u"- */select/1/1/1/\n"
4403+ u"testfiles/select/1/1/\n"
4404+ u"- testfiles/*/1/\n"
4405+ u"- **"])
4406
4407 def test_include_filelist_trailing_slashes_and_double_asterisks(self):
4408 """Filelist glob test similar to globbing filelist, but with trailing slashes and double asterisks"""
4409 # Regression test for Bug #932482 (https://bugs.launchpad.net/duplicity/+bug/932482)
4410- self.ParseTest([("--include-filelist", "file")],
4411- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4412- ('1', '1', '3')],
4413- ["- **/1/1/1/\n"
4414- "testfiles/select/1/1/\n"
4415- "- **t/1/\n"
4416- "- **"])
4417+ self.ParseTest([(u"--include-filelist", u"file")],
4418+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4419+ (u"1", u"1", u"3")],
4420+ [u"- **/1/1/1/\n"
4421+ u"testfiles/select/1/1/\n"
4422+ u"- **t/1/\n"
4423+ u"- **"])
4424
4425 def test_filelist_null_separator(self):
4426 """test_filelist, but with null_separator set"""
4427- self.set_global('null_separator', 1)
4428- self.ParseTest([("--include-filelist", "file")],
4429- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4430- ('1', '1', '3')],
4431- ["\0- testfiles/select/1/1/1\0testfiles/select/1/1\0- testfiles/select/1\0- **\0"])
4432+ self.set_global(u"null_separator", 1)
4433+ self.ParseTest([(u"--include-filelist", u"file")],
4434+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4435+ (u"1", u"1", u"3")],
4436+ [u"\0- testfiles/select/1/1/1\0testfiles/select/1/1\0- testfiles/select/1\0- **\0"])
4437
4438 def test_exclude_filelist(self):
4439 """Exclude version of test_filelist"""
4440- self.ParseTest([("--exclude-filelist", "file")],
4441- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4442- ('1', '1', '3')],
4443- ["testfiles/select/1/1/1\n"
4444- "+ testfiles/select/1/1\n"
4445- "testfiles/select/1\n"
4446- "- **"])
4447+ self.ParseTest([(u"--exclude-filelist", u"file")],
4448+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4449+ (u"1", u"1", u"3")],
4450+ [u"testfiles/select/1/1/1\n"
4451+ u"+ testfiles/select/1/1\n"
4452+ u"testfiles/select/1\n"
4453+ u"- **"])
4454
4455 def test_exclude_filelist_asterisk_1(self):
4456 """Exclude version of test_include_filelist_asterisk"""
4457- self.ParseTest([("--exclude-filelist", "file")],
4458- [(), ('1',), ('1', '1'), ('1', '1', '1'),
4459- ('1', '1', '2'), ('1', '1', '3')],
4460- ["+ */select/1/1\n"
4461- "- **"])
4462+ self.ParseTest([(u"--exclude-filelist", u"file")],
4463+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"1"),
4464+ (u"1", u"1", u"2"), (u"1", u"1", u"3")],
4465+ [u"+ */select/1/1\n"
4466+ u"- **"])
4467
4468 def test_exclude_filelist_asterisk_2(self):
4469- """Identical to test_exclude_filelist, but with the exclude 'select' replaced with '*'"""
4470- self.ParseTest([("--exclude-filelist", "file")],
4471- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4472- ('1', '1', '3')],
4473- ["testfiles/*/1/1/1\n"
4474- "+ testfiles/select/1/1\n"
4475- "testfiles/select/1\n"
4476- "- **"])
4477+ """Identical to test_exclude_filelist, but with the exclude "select" replaced with '*'"""
4478+ self.ParseTest([(u"--exclude-filelist", u"file")],
4479+ [(), (u"1",), (u"1", "1"), (u"1", u"1", u"2"),
4480+ (u"1", u"1", u"3")],
4481+ [u"testfiles/*/1/1/1\n"
4482+ u"+ testfiles/select/1/1\n"
4483+ u"testfiles/select/1\n"
4484+ u"- **"])
4485
4486 def test_exclude_filelist_asterisk_3(self):
4487- """Identical to test_exclude_filelist, but with the include 'select' replaced with '*'"""
4488+ """Identical to test_exclude_filelist, but with the include "select" replaced with '*'"""
4489 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4490- self.ParseTest([("--exclude-filelist", "file")],
4491- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4492- ('1', '1', '3')],
4493- ["testfiles/select/1/1/1\n"
4494- "+ testfiles/*/1/1\n"
4495- "testfiles/select/1\n"
4496- "- **"])
4497+ self.ParseTest([(u"--exclude-filelist", u"file")],
4498+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4499+ (u"1", u"1", u"3")],
4500+ [u"testfiles/select/1/1/1\n"
4501+ u"+ testfiles/*/1/1\n"
4502+ u"testfiles/select/1\n"
4503+ u"- **"])
4504
4505 def test_exclude_filelist_asterisk_4(self):
4506 """Identical to test_exclude_filelist, but with numerous excluded folders replaced with '*'"""
4507- self.ParseTest([("--exclude-filelist", "file")],
4508- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4509- ('1', '1', '3')],
4510- ["*/select/1/1/1\n"
4511- "+ testfiles/select/1/1\n"
4512- "*/*/1\n"
4513- "- **"])
4514+ self.ParseTest([(u"--exclude-filelist", u"file")],
4515+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4516+ (u"1", u"1", u"3")],
4517+ [u"*/select/1/1/1\n"
4518+ u"+ testfiles/select/1/1\n"
4519+ u"*/*/1\n"
4520+ u"- **"])
4521
4522 def test_exclude_filelist_asterisk_5(self):
4523 """Identical to test_exclude_filelist, but with numerous included/excluded folders replaced with '*'"""
4524 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4525- self.ParseTest([("--exclude-filelist", "file")],
4526- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4527- ('1', '1', '3')],
4528- ["*/select/1/1/1\n"
4529- "+ */*/1/1\n"
4530- "*/*/1\n"
4531- "- **"])
4532+ self.ParseTest([(u"--exclude-filelist", u"file")],
4533+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4534+ (u"1", u"1", u"3")],
4535+ [u"*/select/1/1/1\n"
4536+ u"+ */*/1/1\n"
4537+ u"*/*/1\n"
4538+ u"- **"])
4539
4540 def test_exclude_filelist_double_asterisk(self):
4541 """Identical to test_exclude_filelist, but with all included/excluded folders replaced with '**'"""
4542 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4543- self.ParseTest([("--exclude-filelist", "file")],
4544- [(), ('1',), ('1', '1'), ('1', '1', '2'),
4545- ('1', '1', '3')],
4546- ["**/1/1/1\n"
4547- "+ **t/1/1\n"
4548- "**t/1\n"
4549- "- **"])
4550+ self.ParseTest([(u"--exclude-filelist", u"file")],
4551+ [(), (u"1",), (u"1", u"1"), (u"1", u"1", u"2"),
4552+ (u"1", u"1", u"3")],
4553+ [u"**/1/1/1\n"
4554+ u"+ **t/1/1\n"
4555+ u"**t/1\n"
4556+ u"- **"])
4557
4558 def test_exclude_filelist_single_asterisk_at_beginning(self):
4559 """Exclude filelist testing limited functionality of functional test"""
4560 # Regression test for Bug #884371 (https://bugs.launchpad.net/duplicity/+bug/884371)
4561- self.root = Path("testfiles/select/1")
4562- self.ParseTest([("--exclude-filelist", "file")],
4563- [(), ('2',), ('2', '1')],
4564- ["+ */select/1/2/1\n"
4565- "- testfiles/select/1/2\n"
4566- "- testfiles/*/1/1\n"
4567- "- testfiles/select/1/3"])
4568+ self.root = Path(u"testfiles/select/1")
4569+ self.ParseTest([(u"--exclude-filelist", u"file")],
4570+ [(), (u"2",), (u"2", u"1")],
4571+ [u"+ */select/1/2/1\n"
4572+ u"- testfiles/select/1/2\n"
4573+ u"- testfiles/*/1/1\n"
4574+ u"- testfiles/select/1/3"])
4575
4576 def test_commandline_asterisks_double_both(self):
4577 """Unit test the functional test TestAsterisks.test_commandline_asterisks_double_both"""
4578- self.root = Path("testfiles/select/1")
4579- self.ParseTest([("--include", "**/1/2/1"),
4580- ("--exclude", "**t/1/2"),
4581- ("--exclude", "**t/1/1"),
4582- ("--exclude", "**t/1/3")],
4583- [(), ('2',), ('2', '1')])
4584+ self.root = Path(u"testfiles/select/1")
4585+ self.ParseTest([(u"--include", u"**/1/2/1"),
4586+ (u"--exclude", u"**t/1/2"),
4587+ (u"--exclude", u"**t/1/1"),
4588+ (u"--exclude", u"**t/1/3")],
4589+ [(), (u"2",), (u"2", u"1")])
4590
4591 def test_includes_files(self):
4592 """Unit test the functional test test_includes_files"""
4593 # Test for Bug 1624725
4594 # https://bugs.launchpad.net/duplicity/+bug/1624725
4595- self.root = Path("testfiles/select2/1/1sub1")
4596- self.ParseTest([("--include", "testfiles/select2/1/1sub1/1sub1sub1"),
4597- ("--exclude", "**")],
4598- [(), ('1sub1sub1',), ('1sub1sub1',
4599- '1sub1sub1_file.txt')])
4600+ self.root = Path(u"testfiles/select2/1/1sub1")
4601+ self.ParseTest([(u"--include", u"testfiles/select2/1/1sub1/1sub1sub1"),
4602+ (u"--exclude", u"**")],
4603+ [(), (u"1sub1sub1",), (u"1sub1sub1",
4604+ u"1sub1sub1_file.txt")])
4605
4606 def test_includes_files_trailing_slash(self):
4607 """Unit test the functional test test_includes_files_trailing_slash"""
4608 # Test for Bug 1624725
4609 # https://bugs.launchpad.net/duplicity/+bug/1624725
4610- self.root = Path("testfiles/select2/1/1sub1")
4611- self.ParseTest([("--include", "testfiles/select2/1/1sub1/1sub1sub1/"),
4612- ("--exclude", "**")],
4613- [(), ('1sub1sub1',), ('1sub1sub1',
4614- '1sub1sub1_file.txt')])
4615+ self.root = Path(u"testfiles/select2/1/1sub1")
4616+ self.ParseTest([(u"--include", u"testfiles/select2/1/1sub1/1sub1sub1/"),
4617+ (u"--exclude", u"**")],
4618+ [(), (u"1sub1sub1",), (u"1sub1sub1",
4619+ u"1sub1sub1_file.txt")])
4620
4621 def test_includes_files_trailing_slash_globbing_chars(self):
4622 """Unit test functional test_includes_files_trailing_slash_globbing_chars"""
4623 # Test for Bug 1624725
4624 # https://bugs.launchpad.net/duplicity/+bug/1624725
4625- self.root = Path("testfiles/select2/1/1sub1")
4626- self.ParseTest([("--include", "testfiles/s?lect2/1/1sub1/1sub1sub1/"),
4627- ("--exclude", "**")],
4628- [(), ('1sub1sub1',), ('1sub1sub1',
4629- '1sub1sub1_file.txt')])
4630+ self.root = Path(u"testfiles/select2/1/1sub1")
4631+ self.ParseTest([(u"--include", u"testfiles/s?lect2/1/1sub1/1sub1sub1/"),
4632+ (u"--exclude", u"**")],
4633+ [(), (u"1sub1sub1",), (u"1sub1sub1",
4634+ u"1sub1sub1_file.txt")])
4635
4636 def test_glob(self):
4637 """Test globbing expression"""
4638- self.ParseTest([("--exclude", "**[3-5]"),
4639- ("--include", "testfiles/select/1"),
4640- ("--exclude", "**")],
4641- [(), ('1',), ('1', '1'),
4642- ('1', '1', '1'), ('1', '1', '2'),
4643- ('1', '2'), ('1', '2', '1'), ('1', '2', '2')])
4644- self.ParseTest([("--include", "testfiles/select**/2"),
4645- ("--exclude", "**")],
4646- [(), ('1',), ('1', '1'),
4647- ('1', '1', '2'),
4648- ('1', '2'),
4649- ('1', '2', '1'), ('1', '2', '2'), ('1', '2', '3'),
4650- ('1', '3'),
4651- ('1', '3', '2'),
4652- ('2',), ('2', '1'),
4653- ('2', '1', '1'), ('2', '1', '2'), ('2', '1', '3'),
4654- ('2', '2'),
4655- ('2', '2', '1'), ('2', '2', '2'), ('2', '2', '3'),
4656- ('2', '3'),
4657- ('2', '3', '1'), ('2', '3', '2'), ('2', '3', '3'),
4658- ('3',), ('3', '1'),
4659- ('3', '1', '2'),
4660- ('3', '2'),
4661- ('3', '2', '1'), ('3', '2', '2'), ('3', '2', '3'),
4662- ('3', '3'),
4663- ('3', '3', '2')])
4664+ self.ParseTest([(u"--exclude", u"**[3-5]"),
4665+ (u"--include", u"testfiles/select/1"),
4666+ (u"--exclude", u"**")],
4667+ [(), (u"1",), (u"1", u"1"),
4668+ (u"1", u"1", u"1"), (u"1", u"1", u"2"),
4669+ (u"1", u"2"), (u"1", u"2", u"1"), (u"1", u"2", u"2")])
4670+ self.ParseTest([(u"--include", u"testfiles/select**/2"),
4671+ (u"--exclude", u"**")],
4672+ [(), (u"1",), (u"1", u"1"),
4673+ (u"1", u"1", u"2"),
4674+ (u"1", u"2"),
4675+ (u"1", u"2", u"1"), (u"1", u"2", u"2"), (u"1", u"2", u"3"),
4676+ (u"1", u"3"),
4677+ (u"1", u"3", u"2"),
4678+ (u"2",), (u"2", u"1"),
4679+ (u"2", u"1", u"1"), (u"2", u"1", u"2"), (u"2", u"1", u"3"),
4680+ (u"2", u"2"),
4681+ (u"2", u"2", u"1"), (u"2", u"2", u"2"), (u"2", u"2", u"3"),
4682+ (u"2", u"3"),
4683+ (u"2", u"3", u"1"), (u"2", u"3", u"2"), (u"2", u"3", u"3"),
4684+ (u"3",), (u"3", u"1"),
4685+ (u"3", u"1", u"2"),
4686+ (u"3", u"2"),
4687+ (u"3", u"2", u"1"), (u"3", u"2", u"2"), (u"3", u"2", u"3"),
4688+ (u"3", u"3"),
4689+ (u"3", u"3", u"2")])
4690
4691 def test_filelist2(self):
4692 """Filelist glob test similar to above testGlob"""
4693- self.ParseTest([("--exclude-filelist", "asoeuth")],
4694- [(), ('1',), ('1', '1'),
4695- ('1', '1', '1'), ('1', '1', '2'),
4696- ('1', '2'), ('1', '2', '1'), ('1', '2', '2')],
4697- ["""
4698+ self.ParseTest([(u"--exclude-filelist", u"asoeuth")],
4699+ [(), (u"1",), (u"1", u"1"),
4700+ (u"1", u"1", u"1"), (u"1", u"1", u"2"),
4701+ (u"1", u"2"), (u"1", u"2", u"1"), (u"1", u"2", u"2")],
4702+ [u"""
4703 **[3-5]
4704 + testfiles/select/1
4705 **
4706 """])
4707- self.ParseTest([("--include-filelist", "file")],
4708- [(), ('1',), ('1', '1'),
4709- ('1', '1', '2'),
4710- ('1', '2'),
4711- ('1', '2', '1'), ('1', '2', '2'), ('1', '2', '3'),
4712- ('1', '3'),
4713- ('1', '3', '2'),
4714- ('2',), ('2', '1'),
4715- ('2', '1', '1'), ('2', '1', '2'), ('2', '1', '3'),
4716- ('2', '2'),
4717- ('2', '2', '1'), ('2', '2', '2'), ('2', '2', '3'),
4718- ('2', '3'),
4719- ('2', '3', '1'), ('2', '3', '2'), ('2', '3', '3'),
4720- ('3',), ('3', '1'),
4721- ('3', '1', '2'),
4722- ('3', '2'),
4723- ('3', '2', '1'), ('3', '2', '2'), ('3', '2', '3'),
4724- ('3', '3'),
4725- ('3', '3', '2')],
4726- ["""
4727+ self.ParseTest([(u"--include-filelist", u"file")],
4728+ [(), (u"1",), (u"1", u"1"),
4729+ (u"1", u"1", u"2"),
4730+ (u"1", u"2"),
4731+ (u"1", u"2", u"1"), (u"1", u"2", u"2"), (u"1", u"2", u"3"),
4732+ (u"1", u"3"),
4733+ (u"1", u"3", u"2"),
4734+ (u"2",), (u"2", u"1"),
4735+ (u"2", u"1", u"1"), (u"2", u"1", u"2"), (u"2", u"1", u"3"),
4736+ (u"2", u"2"),
4737+ (u"2", u"2", u"1"), (u"2", u"2", u"2"), (u"2", u"2", u"3"),
4738+ (u"2", u"3"),
4739+ (u"2", u"3", u"1"), (u"2", u"3", u"2"), (u"2", u"3", u"3"),
4740+ (u"3",), (u"3", u"1"),
4741+ (u"3", u"1", u"2"),
4742+ (u"3", u"2"),
4743+ (u"3", u"2", u"1"), (u"3", u"2", u"2"), (u"3", u"2", u"3"),
4744+ (u"3", u"3"),
4745+ (u"3", u"3", u"2")],
4746+ [u"""
4747 testfiles/select**/2
4748 - **
4749 """])
4750
4751 def test_glob2(self):
4752 """Test more globbing functions"""
4753- self.ParseTest([("--include", "testfiles/select/*foo*/p*"),
4754- ("--exclude", "**")],
4755- [(), ('efools',), ('efools', 'ping'),
4756- ('foobar',), ('foobar', 'pong')])
4757- self.ParseTest([("--exclude", "testfiles/select/1/1/*"),
4758- ("--exclude", "testfiles/select/1/2/**"),
4759- ("--exclude", "testfiles/select/1/3**"),
4760- ("--include", "testfiles/select/1"),
4761- ("--exclude", "**")],
4762- [(), ('1',), ('1', '1'), ('1', '2')])
4763+ self.ParseTest([(u"--include", u"testfiles/select/*foo*/p*"),
4764+ (u"--exclude", u"**")],
4765+ [(), (u"efools",), (u"efools", u"ping"),
4766+ (u"foobar",), (u"foobar", u"pong")])
4767+ self.ParseTest([(u"--exclude", u"testfiles/select/1/1/*"),
4768+ (u"--exclude", u"testfiles/select/1/2/**"),
4769+ (u"--exclude", u"testfiles/select/1/3**"),
4770+ (u"--include", u"testfiles/select/1"),
4771+ (u"--exclude", u"**")],
4772+ [(), (u"1",), (u"1", u"1"), (u"1", u"2")])
4773
4774 def test_glob3(self):
4775 """ regression test for bug 25230 """
4776- self.ParseTest([("--include", "testfiles/select/**1"),
4777- ("--include", "testfiles/select/**2"),
4778- ("--exclude", "**")],
4779- [(), ('1',), ('1', '1'),
4780- ('1', '1', '1'), ('1', '1', '2'), ('1', '1', '3'),
4781- ('1', '2'),
4782- ('1', '2', '1'), ('1', '2', '2'), ('1', '2', '3'),
4783- ('1', '3'),
4784- ('1', '3', '1'), ('1', '3', '2'), ('1', '3', '3'),
4785- ('2',), ('2', '1'),
4786- ('2', '1', '1'), ('2', '1', '2'), ('2', '1', '3'),
4787- ('2', '2'),
4788- ('2', '2', '1'), ('2', '2', '2'), ('2', '2', '3'),
4789- ('2', '3'),
4790- ('2', '3', '1'), ('2', '3', '2'), ('2', '3', '3'),
4791- ('3',), ('3', '1'),
4792- ('3', '1', '1'), ('3', '1', '2'), ('3', '1', '3'),
4793- ('3', '2'),
4794- ('3', '2', '1'), ('3', '2', '2'), ('3', '2', '3'),
4795- ('3', '3'),
4796- ('3', '3', '1'), ('3', '3', '2')])
4797+ self.ParseTest([(u"--include", u"testfiles/select/**1"),
4798+ (u"--include", u"testfiles/select/**2"),
4799+ (u"--exclude", u"**")],
4800+ [(), (u"1",), (u"1", u"1"),
4801+ (u"1", u"1", u"1"), (u"1", u"1", u"2"), (u"1", u"1", u"3"),
4802+ (u"1", u"2"),
4803+ (u"1", u"2", u"1"), (u"1", u"2", u"2"), (u"1", u"2", u"3"),
4804+ (u"1", u"3"),
4805+ (u"1", u"3", u"1"), (u"1", u"3", u"2"), (u"1", u"3", u"3"),
4806+ (u"2",), (u"2", u"1"),
4807+ (u"2", u"1", u"1"), (u"2", u"1", u"2"), (u"2", u"1", u"3"),
4808+ (u"2", u"2"),
4809+ (u"2", u"2", u"1"), (u"2", u"2", u"2"), (u"2", u"2", u"3"),
4810+ (u"2", u"3"),
4811+ (u"2", u"3", u"1"), (u"2", u"3", u"2"), (u"2", u"3", u"3"),
4812+ (u"3",), (u"3", u"1"),
4813+ (u"3", u"1", u"1"), (u"3", u"1", u"2"), (u"3", u"1", u"3"),
4814+ (u"3", u"2"),
4815+ (u"3", u"2", u"1"), (u"3", u"2", u"2"), (u"3", u"2", u"3"),
4816+ (u"3", u"3"),
4817+ (u"3", u"3", u"1"), (u"3", u"3", u"2")])
4818
4819 def test_alternate_root(self):
4820 """Test select with different root"""
4821- self.root = Path("testfiles/select/1")
4822- self.ParseTest([("--exclude", "testfiles/select/1/[23]")],
4823- [(), ('1',), ('1', '1'), ('1', '2'), ('1', '3')])
4824+ self.root = Path(u"testfiles/select/1")
4825+ self.ParseTest([(u"--exclude", u"testfiles/select/1/[23]")],
4826+ [(), (u"1",), (u"1", u"1"), (u"1", u"2"), (u"1", u"3")])
4827
4828- self.root = Path("/")
4829- self.ParseTest([("--exclude", "/tmp/*"),
4830- ("--include", "/tmp"),
4831- ("--exclude", "/")],
4832- [(), ("tmp",)])
4833+ self.root = Path(u"/")
4834+ self.ParseTest([(u"--exclude", u"/tmp/*"),
4835+ (u"--include", u"/tmp"),
4836+ (u"--exclude", u"/")],
4837+ [(), (u"tmp",)])
4838
4839 def test_exclude_after_scan(self):
4840 """Test select with an exclude after a pattern that would return a scan for that file"""
4841- self.root = Path("testfiles/select2/3")
4842- self.ParseTest([("--include", "testfiles/select2/3/**file.txt"),
4843- ("--exclude", "testfiles/select2/3/3sub2"),
4844- ("--include", "testfiles/select2/3/3sub1"),
4845- ("--exclude", "**")],
4846- [(), ('3sub1',), ('3sub1', '3sub1sub1'), ('3sub1', '3sub1sub2'), ('3sub1', '3sub1sub3'),
4847- ('3sub3',), ('3sub3', '3sub3sub2'), ('3sub3', '3sub3sub2', '3sub3sub2_file.txt')])
4848+ self.root = Path(u"testfiles/select2/3")
4849+ self.ParseTest([(u"--include", u"testfiles/select2/3/**file.txt"),
4850+ (u"--exclude", u"testfiles/select2/3/3sub2"),
4851+ (u"--include", u"testfiles/select2/3/3sub1"),
4852+ (u"--exclude", u"**")],
4853+ [(), (u"3sub1",), (u"3sub1", u"3sub1sub1"), (u"3sub1", u"3sub1sub2"), (u"3sub1", u"3sub1sub3"),
4854+ (u"3sub3",), (u"3sub3", u"3sub3sub2"), (u"3sub3", u"3sub3sub2", u"3sub3sub2_file.txt")])
4855
4856 def test_include_exclude_basic(self):
4857 """Test functional test test_include_exclude_basic as a unittest"""
4858- self.root = Path("testfiles/select2")
4859- self.ParseTest([("--include", "testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt"),
4860- ("--exclude", "testfiles/select2/3/3sub3/3sub3sub2"),
4861- ("--include", "testfiles/select2/3/3sub2/3sub2sub2"),
4862- ("--include", "testfiles/select2/3/3sub3"),
4863- ("--exclude", "testfiles/select2/3/3sub1"),
4864- ("--exclude", "testfiles/select2/2/2sub1/2sub1sub3"),
4865- ("--exclude", "testfiles/select2/2/2sub1/2sub1sub2"),
4866- ("--include", "testfiles/select2/2/2sub1"),
4867- ("--exclude", "testfiles/select2/1/1sub3/1sub3sub2"),
4868- ("--exclude", "testfiles/select2/1/1sub3/1sub3sub1"),
4869- ("--exclude", "testfiles/select2/1/1sub2/1sub2sub3"),
4870- ("--include", "testfiles/select2/1/1sub2/1sub2sub1"),
4871- ("--exclude", "testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt"),
4872- ("--exclude", "testfiles/select2/1/1sub1/1sub1sub2"),
4873- ("--exclude", "testfiles/select2/1/1sub2"),
4874- ("--include", "testfiles/select2/1.py"),
4875- ("--include", "testfiles/select2/3"),
4876- ("--include", "testfiles/select2/1"),
4877- ("--exclude", "testfiles/select2/**")],
4878+ self.root = Path(u"testfiles/select2")
4879+ self.ParseTest([(u"--include", u"testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt"),
4880+ (u"--exclude", u"testfiles/select2/3/3sub3/3sub3sub2"),
4881+ (u"--include", u"testfiles/select2/3/3sub2/3sub2sub2"),
4882+ (u"--include", u"testfiles/select2/3/3sub3"),
4883+ (u"--exclude", u"testfiles/select2/3/3sub1"),
4884+ (u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub3"),
4885+ (u"--exclude", u"testfiles/select2/2/2sub1/2sub1sub2"),
4886+ (u"--include", u"testfiles/select2/2/2sub1"),
4887+ (u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub2"),
4888+ (u"--exclude", u"testfiles/select2/1/1sub3/1sub3sub1"),
4889+ (u"--exclude", u"testfiles/select2/1/1sub2/1sub2sub3"),
4890+ (u"--include", u"testfiles/select2/1/1sub2/1sub2sub1"),
4891+ (u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt"),
4892+ (u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub2"),
4893+ (u"--exclude", u"testfiles/select2/1/1sub2"),
4894+ (u"--include", u"testfiles/select2/1.py"),
4895+ (u"--include", u"testfiles/select2/3"),
4896+ (u"--include", u"testfiles/select2/1"),
4897+ (u"--exclude", u"testfiles/select2/**")],
4898 self.expected_restored_tree)
4899
4900 def test_globbing_replacement(self):
4901 """Test functional test test_globbing_replacement as a unittest"""
4902- self.root = Path("testfiles/select2")
4903- self.ParseTest([("--include", "testfiles/select2/**/3sub3sub2/3sub3su?2_file.txt"),
4904- ("--exclude", "testfiles/select2/*/3s*1"),
4905- ("--exclude", "testfiles/select2/**/2sub1sub3"),
4906- ("--exclude", "ignorecase:testfiles/select2/2/2sub1/2Sub1Sub2"),
4907- ("--include", "ignorecase:testfiles/sel[w,u,e,q]ct2/2/2S?b1"),
4908- ("--exclude", "testfiles/select2/1/1sub3/1s[w,u,p,q]b3sub2"),
4909- ("--exclude", "testfiles/select2/1/1sub[1-4]/1sub3sub1"),
4910- ("--include", "testfiles/select2/1/1sub2/1sub2sub1"),
4911- ("--exclude", "testfiles/select2/1/1sub1/1sub1sub3/1su?1sub3_file.txt"),
4912- ("--exclude", "testfiles/select2/1/1*1/1sub1sub2"),
4913- ("--exclude", "testfiles/select2/1/1sub2"),
4914- ("--include", "testfiles/select[2-4]/*.py"),
4915- ("--include", "testfiles/*2/3"),
4916- ("--include", "**/select2/1"),
4917- ("--exclude", "testfiles/select2/**")],
4918+ self.root = Path(u"testfiles/select2")
4919+ self.ParseTest([(u"--include", u"testfiles/select2/**/3sub3sub2/3sub3su?2_file.txt"),
4920+ (u"--exclude", u"testfiles/select2/*/3s*1"),
4921+ (u"--exclude", u"testfiles/select2/**/2sub1sub3"),
4922+ (u"--exclude", u"ignorecase:testfiles/select2/2/2sub1/2Sub1Sub2"),
4923+ (u"--include", u"ignorecase:testfiles/sel[w,u,e,q]ct2/2/2S?b1"),
4924+ (u"--exclude", u"testfiles/select2/1/1sub3/1s[w,u,p,q]b3sub2"),
4925+ (u"--exclude", u"testfiles/select2/1/1sub[1-4]/1sub3sub1"),
4926+ (u"--include", u"testfiles/select2/1/1sub2/1sub2sub1"),
4927+ (u"--exclude", u"testfiles/select2/1/1sub1/1sub1sub3/1su?1sub3_file.txt"),
4928+ (u"--exclude", u"testfiles/select2/1/1*1/1sub1sub2"),
4929+ (u"--exclude", u"testfiles/select2/1/1sub2"),
4930+ (u"--include", u"testfiles/select[2-4]/*.py"),
4931+ (u"--include", u"testfiles/*2/3"),
4932+ (u"--include", u"**/select2/1"),
4933+ (u"--exclude", u"testfiles/select2/**")],
4934 self.expected_restored_tree)
4935
4936+ def test_unicode_paths_non_globbing(self):
4937+ """Test functional test test_unicode_paths_non_globbing as a unittest"""
4938+ self.root = Path(u"testfiles/select-unicode")
4939+ self.ParseTest([(u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/Παράδειγμα/उदाहरण.txt"),
4940+ (u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/Παράδειγμα/דוגמא.txt"),
4941+ (u"--exclude", u"testfiles/select-unicode/прыклад/пример/例/მაგალითი/"),
4942+ (u"--include", u"testfiles/select-unicode/прыклад/пример/例/"),
4943+ (u"--exclude", u"testfiles/select-unicode/прыклад/пример/"),
4944+ (u"--include", u"testfiles/select-unicode/прыклад/"),
4945+ (u"--include", u"testfiles/select-unicode/օրինակ.txt"),
4946+ (u"--exclude", u"testfiles/select-unicode/**")],
4947+ [(), (u"прыклад",), (u"прыклад", u"пример"), (u"прыклад", u"пример", u"例"),
4948+ (u"прыклад", u"пример", u"例", u"Παράδειγμα"),
4949+ (u"прыклад", u"пример", u"例", u"Παράδειγμα", u"ઉદાહરણ.log"),
4950+ (u"прыклад", u"উদাহরণ"), (u"օրինակ.txt",)])
4951+
4952
4953 class TestGlobGetNormalSf(UnitTestCase):
4954 """Test glob parsing of the test_glob_get_normal_sf function. Indirectly test behaviour of glob_to_re."""
4955@@ -877,152 +904,152 @@
4956 path = Path(path)
4957 return selection_function(path)
4958
4959- def include_glob_tester(self, path, glob_string, root_path="/"):
4960+ def include_glob_tester(self, path, glob_string, root_path=u"/"):
4961 return self.glob_tester(path, glob_string, 1, root_path)
4962
4963- def exclude_glob_tester(self, path, glob_string, root_path="/"):
4964+ def exclude_glob_tester(self, path, glob_string, root_path=u"/"):
4965 return self.glob_tester(path, glob_string, 0, root_path)
4966
4967 def test_glob_get_normal_sf_exclude(self):
4968 """Test simple exclude."""
4969- self.assertEqual(self.exclude_glob_tester("/testfiles/select2/3", "/testfiles/select2"), 0)
4970- self.assertEqual(self.exclude_glob_tester("/testfiles/.git", "/testfiles"), 0)
4971+ self.assertEqual(self.exclude_glob_tester(u"/testfiles/select2/3", u"/testfiles/select2"), 0)
4972+ self.assertEqual(self.exclude_glob_tester(u"/testfiles/.git", u"/testfiles"), 0)
4973
4974 def test_glob_get_normal_sf_exclude_root(self):
4975 """Test simple exclude with / as the glob."""
4976- self.assertEqual(self.exclude_glob_tester("/.git", "/"), 0)
4977- self.assertEqual(self.exclude_glob_tester("/testfile", "/"), 0)
4978+ self.assertEqual(self.exclude_glob_tester(u"/.git", u"/"), 0)
4979+ self.assertEqual(self.exclude_glob_tester(u"/testfile", u"/"), 0)
4980
4981 def test_glob_get_normal_sf_2(self):
4982 """Test same behaviour as the functional test test_globbing_replacement."""
4983- self.assertEqual(self.include_glob_tester("/testfiles/select2/3/3sub3/3sub3sub2/3sub3sub2_file.txt",
4984- "/testfiles/select2/**/3sub3sub2/3sub3su?2_file.txt"), 1)
4985- self.assertEqual(self.include_glob_tester("/testfiles/select2/3/3sub1", "/testfiles/select2/*/3s*1"), 1)
4986- self.assertEqual(self.include_glob_tester("/testfiles/select2/2/2sub1/2sub1sub3",
4987- "/testfiles/select2/**/2sub1sub3"), 1)
4988- self.assertEqual(self.include_glob_tester("/testfiles/select2/2/2sub1",
4989- "/testfiles/sel[w,u,e,q]ct2/2/2s?b1"), 1)
4990- self.assertEqual(self.include_glob_tester("/testfiles/select2/1/1sub3/1sub3sub2",
4991- "/testfiles/select2/1/1sub3/1s[w,u,p,q]b3sub2"), 1)
4992- self.assertEqual(self.exclude_glob_tester("/testfiles/select2/1/1sub3/1sub3sub1",
4993- "/testfiles/select2/1/1sub[1-4]/1sub3sub1"), 0)
4994- self.assertEqual(self.include_glob_tester("/testfiles/select2/1/1sub2/1sub2sub1",
4995- "/testfiles/select2/*/1sub2/1s[w,u,p,q]b2sub1"), 1)
4996- self.assertEqual(self.include_glob_tester("/testfiles/select2/1/1sub1/1sub1sub3/1sub1sub3_file.txt",
4997- "/testfiles/select2/1/1sub1/1sub1sub3/1su?1sub3_file.txt"), 1)
4998- self.assertEqual(self.exclude_glob_tester("/testfiles/select2/1/1sub1/1sub1sub2",
4999- "/testfiles/select2/1/1*1/1sub1sub2"), 0)
5000- self.assertEqual(self.include_glob_tester("/testfiles/select2/1/1sub2", "/testfiles/select2/1/1sub2"), 1)
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches