Merge lp:~mterry/deja-dup/verify into lp:deja-dup/24

Proposed by Michael Terry on 2012-08-10
Status: Merged
Merged at revision: 1378
Proposed branch: lp:~mterry/deja-dup/verify
Merge into: lp:deja-dup/24
Diff against target: 700 lines (+274/-43)
22 files modified
common/Makefile.am (+5/-1)
common/Operation.vala (+53/-5)
common/OperationBackup.vala (+50/-5)
common/OperationRestore.vala (+3/-8)
common/OperationVerify.vala (+85/-0)
common/RecursiveDelete.vala (+4/-1)
common/RecursiveMove.vala (+4/-1)
common/RecursiveOp.vala (+4/-1)
po/POTFILES.in (+4/-3)
po/POTFILES.skip (+4/-3)
tests/runner/runner.vala (+12/-2)
tests/scripts/bad-hostname.test (+1/-1)
tests/scripts/clean-incomplete.test (+1/-1)
tests/scripts/encrypt-ask.test (+13/-1)
tests/scripts/encrypt-regex.test (+12/-1)
tests/scripts/read-error.test (+1/-1)
tests/scripts/threshold-full.test (+1/-1)
tests/scripts/threshold-inc.test (+1/-1)
tests/scripts/verify.test (+10/-0)
tools/duplicity/DuplicityInstance.vala (+4/-1)
tools/duplicity/DuplicityJob.vala (+1/-1)
tools/duplicity/Makefile.am (+1/-4)
To merge this branch: bzr merge lp:~mterry/deja-dup/verify
Reviewer Review Type Date Requested Status
Robert Bruce Park (community) Approve on 2012-08-20
Ken VanDine 2012-08-10 Pending
Review via email: mp+119176@code.launchpad.net

Description of the change

This branch does two things:

1) Every backup now also backs up a file created by Deja Dup: ~/.cache/deja-dup/metadata/README which holds the following:

This folder can be safely deleted.
@SECONDS_SINCE_EPOCH@

Where obviously, @SECONDS_SINCE_EPOCH@ is a number.

Intentionally, part of it is always the same (the safely deleted part) and part of it is always different. This means duplicity will always back it up, so it will be present in every backup. And the part that is the same can be sanity-checked.

It doesn't matter if the user sets their cache directory in some weird place, since we always currently use this file right after a backup, so the cache directory will be in the same place we expect it.

2) After each backup, we restore this file and sanity check it. This will have to download one volume from each incremental backup since the start. The idea is to test that the backup can be restored if needed. This isn't 100% foolproof, but will test for a lot of different problems.

The next step in this plan (and a different branch altogether) will be to add logic that every now and then tries to restore without using saved knowledge like the user's encryption password or duplicity cached data, to really test that the user remembers enough to restore if needed.

To post a comment you must log in.
lp:~mterry/deja-dup/verify updated on 2012-08-13
1375. By Michael Terry on 2012-08-13

merge from trunk

1376. By Michael Terry on 2012-08-13

merge from trunk

Robert Bruce Park (robru) wrote :

Looks good, all tests pass, backup and restore both function.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'common/Makefile.am'
2--- common/Makefile.am 2012-08-08 01:12:17 +0000
3+++ common/Makefile.am 2012-08-13 23:46:19 +0000
4@@ -48,10 +48,14 @@
5 Network.vala \
6 Operation.vala \
7 OperationBackup.vala \
8+ OperationFiles.vala \
9 OperationRestore.vala \
10 OperationStatus.vala \
11- OperationFiles.vala \
12+ OperationVerify.vala \
13 PythonChecker.vala \
14+ RecursiveDelete.vala \
15+ RecursiveMove.vala \
16+ RecursiveOp.vala \
17 SimpleSettings.vala \
18 ToolPlugin.vala
19
20
21=== modified file 'common/Operation.vala'
22--- common/Operation.vala 2012-08-06 22:41:13 +0000
23+++ common/Operation.vala 2012-08-13 23:46:19 +0000
24@@ -90,17 +90,19 @@
25 internal ToolJob job;
26 protected string passphrase;
27 bool finished = false;
28+ string saved_detail = null;
29 construct
30 {
31 backend = Backend.get_default();
32 }
33
34- public async virtual void start()
35+ public async virtual void start(bool try_claim_bus = true)
36 {
37 action_desc_changed(_("Preparing…"));
38
39 try {
40- claim_bus();
41+ if (try_claim_bus)
42+ claim_bus();
43 }
44 catch (Error e) {
45 raise_error(e.message, null);
46@@ -182,7 +184,7 @@
47 job.done.connect((d, o, c, detail) => {operation_finished.begin(d, o, c, detail);});
48 job.raise_error.connect((d, s, detail) => {raise_error(s, detail);});
49 job.action_desc_changed.connect((d, s) => {action_desc_changed(s);});
50- job.action_file_changed.connect((d, f, b) => {action_file_changed(f, b);});
51+ job.action_file_changed.connect((d, f, b) => {send_action_file_changed(f, b);});
52 job.progress.connect((d, p) => {progress(p);});
53 job.question.connect((d, t, m) => {question(t, m);});
54 job.is_full.connect((first) => {is_full(first);});
55@@ -195,6 +197,11 @@
56 });
57 }
58
59+ protected virtual void send_action_file_changed(File file, bool actual)
60+ {
61+ action_file_changed(file, actual);
62+ }
63+
64 public void set_passphrase(string? passphrase)
65 {
66 needs_password = false;
67@@ -222,7 +229,47 @@
68 */
69 return null;
70 }
71-
72+
73+ static string combine_details(string? old_detail, string? new_detail)
74+ {
75+ if (old_detail == null)
76+ return new_detail;
77+ else if (new_detail == null)
78+ return old_detail;
79+ else
80+ return old_detail + "\n\n" + new_detail;
81+ }
82+
83+ protected async void chain_op(Operation subop, string desc, string? detail)
84+ {
85+ /**
86+ * Sometimes an operation wants to chain to a separate operation.
87+ * Here is the glue to make that happen.
88+ */
89+ subop.ref();
90+ subop.done.connect((s, c, d) => {
91+ done(s, c, combine_details(saved_detail, d));
92+ subop.unref();
93+ });
94+ subop.raise_error.connect((e, d) => {raise_error(e, d);});
95+ subop.progress.connect((p) => {progress(p);});
96+ subop.passphrase_required.connect(() => {
97+ passphrase_required();
98+ subop.needs_password = needs_password;
99+ subop.passphrase = passphrase;
100+ });
101+ subop.question.connect((t, m) => {question(t, m);});
102+
103+ saved_detail = combine_details(saved_detail, detail);
104+ subop.set_state(get_state());
105+ job = subop.job;
106+
107+ action_desc_changed(desc);
108+ progress(0);
109+
110+ yield subop.start(false);
111+ }
112+
113 uint bus_id = 0;
114 void claim_bus() throws BackupError
115 {
116@@ -239,7 +286,8 @@
117
118 void unclaim_bus()
119 {
120- Bus.unown_name(bus_id);
121+ if (bus_id > 0)
122+ Bus.unown_name(bus_id);
123 }
124 }
125
126
127=== modified file 'common/OperationBackup.vala'
128--- common/OperationBackup.vala 2012-08-06 22:41:13 +0000
129+++ common/OperationBackup.vala 2012-08-13 23:46:19 +0000
130@@ -23,6 +23,8 @@
131
132 public class OperationBackup : Operation
133 {
134+ File metadir;
135+
136 public OperationBackup() {
137 Object(mode: ToolJob.Mode.BACKUP);
138 }
139@@ -32,10 +34,24 @@
140 /* If successfully completed, update time of last backup and run base operation_finished */
141 if (success)
142 DejaDup.update_last_run_timestamp(DejaDup.TimestampType.BACKUP);
143-
144- yield base.operation_finished(job, success, cancelled, detail);
145- }
146-
147+
148+ if (metadir != null)
149+ new RecursiveDelete(metadir).start();
150+
151+ if (success && !cancelled)
152+ yield chain_op(new OperationVerify(), _("Verifying backup…"), detail);
153+ else
154+ yield base.operation_finished(job, success, cancelled, detail);
155+ }
156+
157+ protected override void send_action_file_changed(File file, bool actual)
158+ {
159+ // Intercept action_file_changed signals and ignore them if they are
160+ // metadata file, the user doesn't need to see them.
161+ if (!file.has_prefix(metadir))
162+ base.send_action_file_changed(file, actual);
163+ }
164+
165 protected override List<string>? make_argv()
166 {
167 var settings = get_settings();
168@@ -54,9 +70,20 @@
169 job.excludes.prepend(s);
170 foreach (File s in include_list)
171 job.includes.prepend(s);
172+
173+ // Insert deja-dup meta info directory
174+ string cachedir = Environment.get_user_cache_dir();
175+ try {
176+ metadir = File.new_for_path(Path.build_filename(cachedir, Config.PACKAGE, "metadata"));
177+ fill_metadir();
178+ job.includes.prepend(metadir);
179+ }
180+ catch (Error e) {
181+ warning("%s\n", e.message);
182+ }
183
184 job.local = File.new_for_path("/");
185-
186+
187 return null;
188 }
189
190@@ -99,6 +126,24 @@
191
192 return rv;
193 }
194+
195+ void fill_metadir() throws Error
196+ {
197+ if (metadir == null)
198+ return;
199+
200+ // Delete old dir, if any, and replace it
201+ new RecursiveDelete(metadir).start();
202+ metadir.make_directory_with_parents(null);
203+
204+ // Put a file in there that is one part always constant, and one part
205+ // always different, for basic sanity checking. This way, it will be
206+ // included in every backup, but we can still check its contents for
207+ // corruption. We'll stuff seconds-since-epoch in it.
208+ var now = new DateTime.now_utc();
209+ var msg = "This folder can be safely deleted.\n%s".printf(now.format("%s"));
210+ FileUtils.set_contents(Path.build_filename(metadir.get_path(), "README"), msg);
211+ }
212 }
213
214 } // end namespace
215
216=== modified file 'common/OperationRestore.vala'
217--- common/OperationRestore.vala 2012-08-06 22:41:13 +0000
218+++ common/OperationRestore.vala 2012-08-13 23:46:19 +0000
219@@ -46,20 +46,15 @@
220 mode: ToolJob.Mode.RESTORE);
221 }
222
223- public async override void start()
224+ public async override void start(bool try_claim_bus = true)
225 {
226 action_desc_changed(_("Restoring files…"));
227- yield base.start();
228+ yield base.start(try_claim_bus);
229 }
230
231- protected override void connect_to_job()
232+ protected override List<string>? make_argv()
233 {
234- base.connect_to_job();
235 job.restore_files = restore_files;
236- }
237-
238- protected override List<string>? make_argv()
239- {
240 job.time = time;
241 job.local = File.new_for_path(dest);
242 return null;
243
244=== added file 'common/OperationVerify.vala'
245--- common/OperationVerify.vala 1970-01-01 00:00:00 +0000
246+++ common/OperationVerify.vala 2012-08-13 23:46:19 +0000
247@@ -0,0 +1,85 @@
248+/* -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2 -*- */
249+/*
250+ This file is part of Déjà Dup.
251+ For copyright information, see AUTHORS.
252+
253+ Déjà Dup is free software: you can redistribute it and/or modify
254+ it under the terms of the GNU General Public License as published by
255+ the Free Software Foundation, either version 3 of the License, or
256+ (at your option) any later version.
257+
258+ Déjà Dup is distributed in the hope that it will be useful,
259+ but WITHOUT ANY WARRANTY; without even the implied warranty of
260+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
261+ GNU General Public License for more details.
262+
263+ You should have received a copy of the GNU General Public License
264+ along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
265+*/
266+
267+using GLib;
268+
269+namespace DejaDup {
270+
271+/* This is meant to be used right after a successful OperationBackup to
272+ verify the results. */
273+
274+public class OperationVerify : Operation
275+{
276+ File metadir;
277+ File destdir;
278+
279+ public OperationVerify() {
280+ Object(mode: ToolJob.Mode.RESTORE);
281+ }
282+
283+ public async override void start(bool try_claim_bus = true)
284+ {
285+ action_desc_changed(_("Verifying backup…"));
286+ yield base.start(try_claim_bus);
287+ }
288+
289+ protected override void connect_to_job()
290+ {
291+ string cachedir = Environment.get_user_cache_dir();
292+ metadir = File.new_for_path(Path.build_filename(cachedir, Config.PACKAGE, "metadata"));
293+ job.restore_files.append(metadir);
294+
295+ destdir = File.new_for_path("/");
296+ job.local = destdir;
297+
298+ base.connect_to_job();
299+ }
300+
301+ internal async override void operation_finished(ToolJob job, bool success, bool cancelled, string? detail)
302+ {
303+ // Verify results
304+ if (success) {
305+ var verified = true;
306+ string contents;
307+ try {
308+ FileUtils.get_contents(Path.build_filename(metadir.get_path(), "README"), out contents);
309+ }
310+ catch (Error e) {
311+ verified = false;
312+ }
313+
314+ if (verified) {
315+ var lines = contents.split("\n");
316+ verified = (lines[0] == "This folder can be safely deleted.");
317+ }
318+
319+ if (!verified) {
320+ raise_error(_("Your backup appears to be corrupted. You should delete the backup and try again."), null);
321+ success = false;
322+ }
323+ }
324+
325+ new RecursiveDelete(metadir).start();
326+
327+ yield base.operation_finished(job, success, cancelled, detail);
328+ }
329+}
330+
331+} // end namespace
332+
333
334=== renamed file 'tools/duplicity/RecursiveDelete.vala' => 'common/RecursiveDelete.vala'
335--- tools/duplicity/RecursiveDelete.vala 2012-04-30 00:18:18 +0000
336+++ common/RecursiveDelete.vala 2012-08-13 23:46:19 +0000
337@@ -19,7 +19,9 @@
338
339 using GLib;
340
341-internal class RecursiveDelete : RecursiveOp
342+namespace DejaDup {
343+
344+public class RecursiveDelete : RecursiveOp
345 {
346 public RecursiveDelete(File source)
347 {
348@@ -57,3 +59,4 @@
349 }
350 }
351
352+} // namespace
353
354=== renamed file 'tools/duplicity/RecursiveMove.vala' => 'common/RecursiveMove.vala'
355--- tools/duplicity/RecursiveMove.vala 2012-04-30 00:18:18 +0000
356+++ common/RecursiveMove.vala 2012-08-13 23:46:19 +0000
357@@ -19,6 +19,8 @@
358
359 using GLib;
360
361+namespace DejaDup {
362+
363 /**
364 * Recursively moves one directory into another, merging files. And by merge,
365 * I mean it overwrites. It skips any files it can't move and reports an
366@@ -27,7 +29,7 @@
367 * This is not optimized for remote files. It's mostly async, but it does the
368 * occasional sync operation.
369 */
370-internal class RecursiveMove : RecursiveOp
371+public class RecursiveMove : RecursiveOp
372 {
373 public RecursiveMove(File source, File dest)
374 {
375@@ -162,3 +164,4 @@
376 }
377 }
378
379+} // namespace
380
381=== renamed file 'tools/duplicity/RecursiveOp.vala' => 'common/RecursiveOp.vala'
382--- tools/duplicity/RecursiveOp.vala 2012-08-07 13:33:53 +0000
383+++ common/RecursiveOp.vala 2012-08-13 23:46:19 +0000
384@@ -19,7 +19,9 @@
385
386 using GLib;
387
388-internal abstract class RecursiveOp : Object
389+namespace DejaDup {
390+
391+public abstract class RecursiveOp : Object
392 {
393 public signal void done();
394 public signal void raise_error(File src, File dst, string errstr);
395@@ -129,3 +131,4 @@
396 }
397 }
398
399+} // namespace
400
401=== modified file 'po/POTFILES.in'
402--- po/POTFILES.in 2012-04-30 00:18:18 +0000
403+++ po/POTFILES.in 2012-08-13 23:46:19 +0000
404@@ -22,7 +22,11 @@
405 common/OperationFiles.vala
406 common/OperationRestore.vala
407 common/OperationStatus.vala
408+common/OperationVerify.vala
409 common/Operation.vala
410+common/RecursiveDelete.vala
411+common/RecursiveMove.vala
412+common/RecursiveOp.vala
413 common/SimpleSettings.vala
414 deja-dup/AssistantBackup.vala
415 deja-dup/AssistantOperation.vala
416@@ -39,9 +43,6 @@
417 tools/duplicity/DuplicityInstance.vala
418 tools/duplicity/DuplicityJob.vala
419 tools/duplicity/DuplicityPlugin.vala
420-tools/duplicity/RecursiveDelete.vala
421-tools/duplicity/RecursiveMove.vala
422-tools/duplicity/RecursiveOp.vala
423 widgets/ConfigBool.vala
424 widgets/ConfigChoice.vala
425 widgets/ConfigDelete.vala
426
427=== modified file 'po/POTFILES.skip'
428--- po/POTFILES.skip 2012-04-30 00:18:18 +0000
429+++ po/POTFILES.skip 2012-08-13 23:46:19 +0000
430@@ -11,7 +11,11 @@
431 common/OperationFiles.c
432 common/OperationRestore.c
433 common/OperationStatus.c
434+common/OperationVerify.c
435 common/Operation.c
436+common/RecursiveDelete.c
437+common/RecursiveMove.c
438+common/RecursiveOp.c
439 common/SimpleSettings.c
440 deja-dup/AssistantBackup.c
441 deja-dup/AssistantOperation.c
442@@ -28,9 +32,6 @@
443 tools/duplicity/DuplicityInstance.c
444 tools/duplicity/DuplicityJob.c
445 tools/duplicity/DuplicityPlugin.c
446-tools/duplicity/RecursiveDelete.c
447-tools/duplicity/RecursiveMove.c
448-tools/duplicity/RecursiveOp.c
449 widgets/ConfigBool.c
450 widgets/ConfigChoice.c
451 widgets/ConfigDelete.c
452
453=== modified file 'tests/runner/runner.vala'
454--- tests/runner/runner.vala 2012-08-13 23:35:45 +0000
455+++ tests/runner/runner.vala 2012-08-13 23:46:19 +0000
456@@ -96,6 +96,7 @@
457 STATUS,
458 DRY,
459 BACKUP,
460+ VERIFY,
461 CLEANUP,
462 RESTORE,
463 RESTORE_STATUS,
464@@ -113,6 +114,8 @@
465 return "cleanup '--force' 'file://%s' '--gio' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", cachedir);
466 else if (mode == Mode.RESTORE)
467 return "'restore' '--gio' '--force' 'file://%s' '%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, restoredir, encrypted ? "" : "'--no-encryption' ", cachedir);
468+ else if (mode == Mode.VERIFY)
469+ return "'restore' '--file-to-restore=%s/deja-dup/metadata' '--gio' '--force' 'file://%s' '%s/deja-dup/metadata' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(cachedir.substring(1), backupdir, cachedir, encrypted ? "" : "'--no-encryption' ", cachedir);
470 else if (mode == Mode.LIST)
471 return "'list-current-files' '--gio' 'file://%s' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(backupdir, encrypted ? "" : "'--no-encryption' ", cachedir);
472
473@@ -137,7 +140,7 @@
474 args += "collection-status ";
475
476 if (mode == Mode.STATUS || mode == Mode.NONE || mode == Mode.DRY || mode == Mode.BACKUP) {
477- args += "'--exclude=%s' ".printf(backupdir);
478+ args += "'--exclude=%s' '--include=%s/deja-dup/metadata' ".printf(backupdir, cachedir);
479
480 string[] excludes1 = {"~/Downloads", "~/.local/share/Trash", "~/.xsession-errors", "~/.thumbnails", "~/.Private", "~/.gvfs", "~/.adobe/Flash_Player/AssetCache"};
481
482@@ -293,7 +296,8 @@
483 string replace_keywords(string in)
484 {
485 var home = Environment.get_home_dir();
486- return in.replace("@HOME@", home);
487+ var cachedir = Environment.get_variable("XDG_CACHE_HOME");
488+ return in.replace("@HOME@", home).replace("@XDG_CACHE_HOME@", cachedir);
489 }
490
491 string run_script(string in)
492@@ -388,6 +392,8 @@
493 mode = Mode.LIST;
494 else if (type == "backup")
495 mode = Mode.BACKUP;
496+ else if (type == "verify")
497+ mode = Mode.VERIFY;
498 else if (type == "restore")
499 mode = Mode.RESTORE;
500 else if (type == "cleanup")
501@@ -395,6 +401,8 @@
502 else
503 assert_not_reached();
504
505+ var cachedir = Environment.get_variable("XDG_CACHE_HOME");
506+
507 var dupscript = "ARGS: " + default_args(br, mode, encrypted, extra_args);
508
509 if (cancel) {
510@@ -413,6 +421,8 @@
511
512 if (script != null)
513 dupscript += "\n" + "SCRIPT: " + script;
514+ else if (mode == Mode.VERIFY)
515+ dupscript += "\n" + "SCRIPT: mkdir -p %s/deja-dup/metadata; echo 'This folder can be safely deleted.\\n0' > %s/deja-dup/metadata/README".printf(cachedir, cachedir);
516
517 if (passphrase)
518 dupscript += "\n" + "PASSPHRASE: test";
519
520=== modified file 'tests/scripts/bad-hostname.test'
521--- tests/scripts/bad-hostname.test 2012-04-18 11:45:19 +0000
522+++ tests/scripts/bad-hostname.test 2012-08-13 23:46:19 +0000
523@@ -2,7 +2,7 @@
524 Type=backup
525
526 [Duplicity]
527-Runs=status;dry 1;dry 2;backup;
528+Runs=status;dry 1;dry 2;backup;status-restore;list;verify;
529
530 [Duplicity dry 1]
531 #ERROR 3 new old
532
533=== modified file 'tests/scripts/clean-incomplete.test'
534--- tests/scripts/clean-incomplete.test 2012-07-27 19:04:29 +0000
535+++ tests/scripts/clean-incomplete.test 2012-08-13 23:46:19 +0000
536@@ -6,7 +6,7 @@
537 Type=backup
538
539 [Duplicity]
540-Runs=status;dry;backup 1;cleanup;backup 2;
541+Runs=status;dry;backup 1;cleanup;backup 2;status-restore;list;verify;
542
543 [Duplicity backup 1]
544 #WARNING 2
545
546=== modified file 'tests/scripts/encrypt-ask.test'
547--- tests/scripts/encrypt-ask.test 2012-08-13 23:03:55 +0000
548+++ tests/scripts/encrypt-ask.test 2012-08-13 23:46:19 +0000
549@@ -3,7 +3,7 @@
550 Passphrases=2
551
552 [Duplicity]
553-Runs=status 1;dry 1;status 2;dry 2;backup 1;status 3;dry 3;backup 2;
554+Runs=status 1;dry 1;status 2;dry 2;backup 1;status 3;dry 3;backup 2;status-restore;list;verify;
555
556 [Duplicity status 1]
557 #DEBUG 1
558@@ -46,3 +46,15 @@
559 [Duplicity backup 2]
560 Encrypted=true
561 Passphrase=true
562+
563+[Duplicity status-restore]
564+Encrypted=true
565+Passphrase=true
566+
567+[Duplicity list]
568+Encrypted=true
569+Passphrase=true
570+
571+[Duplicity verify]
572+Encrypted=true
573+Passphrase=true
574
575=== modified file 'tests/scripts/encrypt-regex.test'
576--- tests/scripts/encrypt-regex.test 2012-08-13 22:20:38 +0000
577+++ tests/scripts/encrypt-regex.test 2012-08-13 23:46:19 +0000
578@@ -2,7 +2,7 @@
579 Type=backup
580
581 [Duplicity]
582-Runs=status;dry;backup;
583+Runs=status;dry;backup;status-restore;list;verify;
584
585 [Duplicity status]
586 #DEBUG 1
587@@ -14,3 +14,14 @@
588
589 [Duplicity backup]
590 Encrypted=true
591+
592+[Duplicity status-restore]
593+#DEBUG 1
594+#. ['duplicity.gpg']
595+Output=true
596+
597+[Duplicity list]
598+Encrypted=true
599+
600+[Duplicity verify]
601+Encrypted=true
602
603=== modified file 'tests/scripts/read-error.test'
604--- tests/scripts/read-error.test 2012-04-18 13:40:40 +0000
605+++ tests/scripts/read-error.test 2012-08-13 23:46:19 +0000
606@@ -5,7 +5,7 @@
607 Detail=Could not back up the following files. Please make sure you are able to open them.\n\n@HOME@/1\n@HOME@/2
608
609 [Duplicity]
610-Runs=status;dry;backup;
611+Runs=status;dry;backup;status-restore;list;verify;
612
613 [Duplicity backup]
614 #WARNING 10 '/blarg'
615
616=== modified file 'tests/scripts/threshold-full.test'
617--- tests/scripts/threshold-full.test 2012-06-21 17:47:50 +0000
618+++ tests/scripts/threshold-full.test 2012-08-13 23:46:19 +0000
619@@ -6,7 +6,7 @@
620 IsFull=true
621
622 [Duplicity]
623-Runs=status;dry;backup;
624+Runs=status;dry;backup;status-restore;list;verify;
625
626 [Duplicity status]
627 #echo "INFO 3"
628
629=== modified file 'tests/scripts/threshold-inc.test'
630--- tests/scripts/threshold-inc.test 2012-06-21 17:47:50 +0000
631+++ tests/scripts/threshold-inc.test 2012-08-13 23:46:19 +0000
632@@ -7,7 +7,7 @@
633 IsFull=false
634
635 [Duplicity]
636-Runs=status;dry;backup;
637+Runs=status;dry;backup;status-restore;list;verify;
638
639 [Duplicity status]
640 #echo "INFO 3"
641
642=== added file 'tests/scripts/verify.test'
643--- tests/scripts/verify.test 1970-01-01 00:00:00 +0000
644+++ tests/scripts/verify.test 2012-08-13 23:46:19 +0000
645@@ -0,0 +1,10 @@
646+[Operation]
647+Type=backup
648+Success=false
649+Error=Your backup appears to be corrupted. You should delete the backup and try again.
650+
651+[Duplicity]
652+Runs=status;dry;backup;status-restore;list;verify;
653+
654+[Duplicity verify]
655+Script=mkdir -p @XDG_CACHE_HOME@/deja-dup/metadata; echo 'Nope' > @XDG_CACHE_HOME@/deja-dup/metadata/README
656
657=== modified file 'tools/duplicity/DuplicityInstance.vala'
658--- tools/duplicity/DuplicityInstance.vala 2012-08-07 13:33:53 +0000
659+++ tools/duplicity/DuplicityInstance.vala 2012-08-13 23:46:19 +0000
660@@ -40,7 +40,10 @@
661 if (!settings.get_boolean(DejaDup.ROOT_PROMPT_KEY))
662 as_root = false;
663 }
664-
665+
666+ if (as_root && Environment.get_variable("DEJA_DUP_TESTING") != null)
667+ as_root = false;
668+
669 // Copy current environment, add custom variables
670 var myenv = Environment.list_variables();
671 int myenv_len = 0;
672
673=== modified file 'tools/duplicity/DuplicityJob.vala'
674--- tools/duplicity/DuplicityJob.vala 2012-08-07 13:33:53 +0000
675+++ tools/duplicity/DuplicityJob.vala 2012-08-13 23:46:19 +0000
676@@ -826,7 +826,7 @@
677 return;
678
679 var cachedir = Path.build_filename(dir, Config.PACKAGE);
680- var del = new RecursiveDelete(File.new_for_path(cachedir));
681+ var del = new DejaDup.RecursiveDelete(File.new_for_path(cachedir));
682 del.start();
683 }
684
685
686=== modified file 'tools/duplicity/Makefile.am'
687--- tools/duplicity/Makefile.am 2012-08-08 01:12:17 +0000
688+++ tools/duplicity/Makefile.am 2012-08-13 23:46:19 +0000
689@@ -37,10 +37,7 @@
690 libduplicity_la_VALASOURCES = \
691 DuplicityInstance.vala \
692 DuplicityJob.vala \
693- DuplicityPlugin.vala \
694- RecursiveDelete.vala \
695- RecursiveMove.vala \
696- RecursiveOp.vala
697+ DuplicityPlugin.vala
698
699 libduplicity_la_SOURCES = \
700 $(libduplicity_la_VALASOURCES)

Subscribers

People subscribed via source and target branches