1
// -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
3
This file is part of Déjà Dup.
4
For copyright information, see AUTHORS.
6
Déjà Dup is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation, either version 3 of the License, or
9
(at your option) any later version.
11
Déjà Dup is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
GNU General Public License for more details.
16
You should have received a copy of the GNU General Public License
17
along with Déjà Dup. If not, see <http://www.gnu.org/licenses/>.
22
void setup_gsettings()
24
var dir = Environment.get_variable("DEJA_DUP_TEST_HOME");
26
var schema_dir = Path.build_filename(dir, "share", "glib-2.0", "schemas");
27
DirUtils.create_with_parents(schema_dir, 0700);
29
var data_dirs = Environment.get_variable("XDG_DATA_DIRS");
30
Environment.set_variable("XDG_DATA_DIRS", "%s:%s".printf(Path.build_filename(dir, "share"), data_dirs), true);
32
if (Posix.system("cp ../../data/org.gnome.DejaDup.gschema.xml %s".printf(schema_dir)) != 0)
33
warning("Could not copy schema to %s", schema_dir);
35
if (Posix.system("glib-compile-schemas %s".printf(schema_dir)) != 0)
36
warning("Could not compile schemas in %s", schema_dir);
38
Environment.set_variable("GSETTINGS_BACKEND", "memory", true);
43
var dir = Environment.get_variable("DEJA_DUP_TEST_HOME");
45
var cachedir = Path.build_filename(dir, "cache");
46
DirUtils.create_with_parents(Path.build_filename(cachedir, "deja-dup"), 0700);
48
Environment.set_variable("DEJA_DUP_TOOLS_PATH", "../../tools/duplicity", true);
49
Environment.set_variable("DEJA_DUP_TEST_MOCKSCRIPT", Path.build_filename(dir, "mockscript"), true);
50
Environment.set_variable("XDG_CACHE_HOME", cachedir, true);
51
Environment.set_variable("PATH", "./mock:" + Environment.get_variable("PATH"), true);
53
var settings = DejaDup.get_settings();
54
settings.set_string(DejaDup.BACKEND_KEY, "file");
55
settings = DejaDup.get_settings(DejaDup.FILE_ROOT);
56
settings.set_string(DejaDup.FILE_PATH_KEY, "/tmp/not/a/thing");
59
void backup_teardown()
61
var path = Environment.get_variable("PATH");
62
if (path.has_prefix("./mock:")) {
63
path = path.substring(7);
64
Environment.set_variable("PATH", path, true);
67
var file = File.new_for_path(Environment.get_variable("DEJA_DUP_TEST_MOCKSCRIPT"));
68
if (file.query_exists(null)) {
69
// Fail the test, something went wrong
70
warning("Mockscript file still exists");
73
file = File.new_for_path("/tmp/not/a/thing");
74
if (file.query_exists(null)) {
83
if (Posix.system("rm -r %s".printf(Environment.get_variable("DEJA_DUP_TEST_HOME"))) != 0)
84
warning("Could not clean TEST_HOME %s", Environment.get_variable("DEJA_DUP_TEST_HOME"));
86
Environment.unset_variable("DEJA_DUP_TEST_MOCKSCRIPT");
87
Environment.unset_variable("XDG_CACHE_HOME");
101
public string default_args(Mode mode = Mode.NONE, bool encrypted = false, string extra = "")
103
var cachedir = Environment.get_variable("XDG_CACHE_HOME");
105
if (mode == Mode.CLEANUP)
106
return "cleanup '--force' 'file:///tmp/not/a/thing' '--gio' '--no-encryption' '--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(cachedir);
107
else if (mode == Mode.RESTORE)
108
return "'restore' '--gio' '--force' 'file:///tmp/not/a/thing' '/tmp/not/a/restore' '--no-encryption' '--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(cachedir);
109
else if (mode == Mode.LIST)
110
return "'list-current-files' '--gio' 'file:///tmp/not/a/thing' '--no-encryption' '--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(cachedir);
112
string source_str = "";
113
if (mode == Mode.DRY || mode == Mode.BACKUP)
114
source_str = "--volsize=50 / ";
117
if (mode == Mode.DRY)
118
dry_str = "--dry-run ";
122
enc_str = "--no-encryption ";
126
if (mode == Mode.STATUS || mode == Mode.RESTORE_STATUS)
127
args += "collection-status ";
129
if (mode == Mode.STATUS || mode == Mode.NONE || mode == Mode.DRY || mode == Mode.BACKUP) {
130
args += "'--exclude=/tmp/not/a/thing' ";
132
string[] excludes1 = {"~/Downloads", "~/.local/share/Trash", "~/.xsession-errors", "~/.thumbnails", "~/.Private", "~/.gvfs", "~/.adobe/Flash_Player/AssetCache"};
134
var user = Environment.get_user_name();
135
string[] excludes2 = {"/home/.ecryptfs/%s/.Private".printf(user), "/sys", "/proc", "/tmp"};
137
foreach (string ex in excludes1) {
138
ex = ex.replace("~", Environment.get_home_dir());
139
if (FileUtils.test (ex, FileTest.EXISTS))
140
args += "'--exclude=%s' ".printf(ex);
143
args += "'--include=%s' ".printf(Environment.get_home_dir());
145
foreach (string ex in excludes2) {
146
ex = ex.replace("~", Environment.get_home_dir());
147
if (FileUtils.test (ex, FileTest.EXISTS))
148
args += "'--exclude=%s' ".printf(ex);
151
args += "'--exclude=%s/deja-dup' '--exclude=%s' '--exclude=**' ".printf(cachedir, cachedir);
154
args += "%s%s'--gio' %s'file:///tmp/not/a/thing' %s'--verbosity=9' '--gpg-options=--no-use-agent' '--archive-dir=%s/deja-dup' '--log-fd=?'".printf(extra, dry_str, source_str, enc_str, cachedir);
159
class BackupRunner : Object
161
public delegate void OpCallback (DejaDup.Operation op);
162
public DejaDup.Operation op = null;
163
public bool success = true;
164
public bool cancelled = false;
165
public string? detail = null;
166
public string? error_str = null;
167
public string? error_detail = null;
168
public OpCallback? callback = null;
169
public bool is_full = true;
173
var loop = new MainLoop(null);
174
op.done.connect((op, s, c, d) => {
175
Test.message("Done: %d, %d, %s", (int)s, (int)c, d);
177
warning("Success didn't match; expected %d, got %d", (int) success, (int) s);
179
warning("Cancel didn't match; expected %d, got %d", (int) cancelled, (int) c);
181
warning("Detail didn't match; expected %s, got %s", detail, d);
185
op.raise_error.connect((str, det) => {
186
Test.message("Error: %s, %s", str, det);
187
if (error_str != str)
188
warning("Error string didn't match; expected %s, got %s", error_str, str);
189
if (error_detail != det)
190
warning("Error detail didn't match; expected %s, got %s", error_detail, det);
194
op.action_desc_changed.connect((action) => {
196
op.action_file_changed.connect((file, actual) => {
198
op.progress.connect((percent) => {
200
op.passphrase_required.connect(() => {
201
Test.message("Passphrase required");
203
op.question.connect((title, msg) => {
204
Test.message("Question asked: %s, %s", title, msg);
206
op.is_full.connect((full) => {
207
Test.message("Is full? %d", (int)full);
209
warning("IsFull didn't match; expected %d, got %d", (int) is_full, (int) full);
213
if (callback != null) {
214
Timeout.add_seconds(5, () => {
221
if (error_str != null)
222
warning("Error str didn't match; expected %s, never got error", error_str);
223
if (error_detail != null)
224
warning("Error detail didn't match; expected %s, never got error", error_detail);
228
void add_to_mockscript(string contents)
230
var script = Environment.get_variable("DEJA_DUP_TEST_MOCKSCRIPT");
233
FileUtils.get_contents(script, out initial, null);
234
initial += "\n\n=== deja-dup ===";
240
var real_contents = initial + "\n" + contents;
242
FileUtils.set_contents(script, real_contents);
245
assert_not_reached();
249
string replace_keywords(string in)
251
var home = Environment.get_home_dir();
252
return in.replace("@HOME@", home);
255
void process_operation_block(KeyFile keyfile, string group, BackupRunner br) throws Error
257
var type = keyfile.get_string(group, "Type");
258
if (type == "backup")
259
br.op = new DejaDup.OperationBackup();
260
else if (type == "restore")
261
br.op = new DejaDup.OperationRestore("/tmp/not/a/restore");
263
assert_not_reached();
264
if (keyfile.has_key(group, "Success"))
265
br.success = keyfile.get_boolean(group, "Success");
266
if (keyfile.has_key(group, "Canceled"))
267
br.cancelled = keyfile.get_boolean(group, "Canceled");
268
if (keyfile.has_key(group, "IsFull"))
269
br.is_full = keyfile.get_boolean(group, "IsFull");
270
if (keyfile.has_key(group, "Detail"))
271
br.detail = replace_keywords(keyfile.get_string(group, "Detail"));
272
if (keyfile.has_key(group, "Error"))
273
br.error_str = keyfile.get_string(group, "Error");
274
if (keyfile.has_key(group, "ErrorDetail"))
275
br.error_detail = keyfile.get_string(group, "ErrorDetail");
278
void process_duplicity_run_block(KeyFile keyfile, string run, BackupRunner br) throws Error
280
string outputscript = null;
281
string extra_args = "";
282
bool encrypted = false;
285
Mode mode = Mode.NONE;
287
var parts = run.split(" ", 2);
289
var group = "Duplicity " + run;
291
if (keyfile.has_group(group)) {
292
if (keyfile.has_key(group, "Cancel"))
293
cancel = keyfile.get_boolean(group, "Cancel");
294
if (keyfile.has_key(group, "Encrypted"))
295
encrypted = keyfile.get_boolean(group, "Encrypted");
296
if (keyfile.has_key(group, "ExtraArgs")) {
297
extra_args = keyfile.get_string(group, "ExtraArgs");
298
if (!extra_args.has_suffix(" "))
301
if (keyfile.has_key(group, "Output") && keyfile.get_boolean(group, "Output"))
302
outputscript = replace_keywords(keyfile.get_comment(group, "Output"));
303
if (keyfile.has_key(group, "Stop"))
304
stop = keyfile.get_boolean(group, "Stop");
307
if (type == "status")
309
else if (type == "status-restore")
310
mode = Mode.RESTORE_STATUS; // should really consolidate the statuses
311
else if (type == "dry")
313
else if (type == "list")
315
else if (type == "backup")
317
else if (type == "restore")
319
else if (type == "cleanup")
322
assert_not_reached();
324
var dupscript = "ARGS: " + default_args(mode, encrypted, extra_args);
327
dupscript += "\n" + "DELAY: 10";
328
br.callback = (op) => {
334
dupscript += "\n" + "DELAY: 10";
335
br.callback = (op) => {
340
if (outputscript != null && outputscript != "")
341
dupscript += "\n\n" + outputscript + "\n";
343
add_to_mockscript(dupscript);
346
void process_duplicity_block(KeyFile keyfile, string group, BackupRunner br) throws Error
348
var runs = keyfile.get_string_list(group, "Runs");
349
foreach (var run in runs)
350
process_duplicity_run_block(keyfile, run, br);
356
var script = Environment.get_variable("DEJA_DUP_TEST_SCRIPT");
357
var keyfile = new KeyFile();
358
keyfile.load_from_file(script, KeyFileFlags.KEEP_COMMENTS);
360
var br = new BackupRunner();
362
var groups = keyfile.get_groups();
363
foreach (var group in groups) {
364
if (group == "Operation")
365
process_operation_block(keyfile, group, br);
366
else if (group == "Duplicity")
367
process_duplicity_block(keyfile, group, br);
373
assert_not_reached();
377
int main(string[] args)
381
var dir = "/tmp/deja-dup-test-XXXXXX";
382
dir = DirUtils.mkdtemp(dir);
383
Environment.set_variable("DEJA_DUP_TEST_HOME", dir, true);
385
Environment.set_variable("DEJA_DUP_LANGUAGE", "en", true);
386
Test.bug_base("https://launchpad.net/bugs/%s");
390
var script = "unknown/unknown";
393
Environment.set_variable("DEJA_DUP_TEST_SCRIPT", script, true);
395
var parts = script.split("/");
396
var suitename = parts[parts.length - 2];
397
var testname = parts[parts.length - 1].split(".")[0];
399
var suite = new TestSuite(suitename);
400
suite.add(new TestCase(testname, backup_setup, backup_run, backup_teardown));
401
TestSuite.get_root().add_suite(suite);