~ubuntu-branches/ubuntu/saucy/deja-dup/saucy

« back to all changes in this revision

Viewing changes to tests/runner/runner.vala

  • Committer: Package Import Robot
  • Author(s): Michael Terry
  • Date: 2012-06-05 13:45:39 UTC
  • mfrom: (1.1.43)
  • Revision ID: package-import@ubuntu.com-20120605134539-l35tewhkjfq4qp6e
Tags: 23.2-0ubuntu1
* New upstream release
* debian/control:
  - Add libpeas-dev to Build-Depends
  - Update valac and libglib2.0-dev versions
  - Bump debhelper version to 9
* debian/compat:
  - Bump to 9
* debian/rules:
  - Don't install new .la and .a files from upstream
* debian/patches/allow-resuming-encrypted-backup.patch:
  - Dropped, included upstream

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: Vala; indent-tabs-mode: nil; tab-width: 2; coding: utf-8 -*-
 
2
/*
 
3
    This file is part of Déjà Dup.
 
4
    For copyright information, see AUTHORS.
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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/>.
 
18
*/
 
19
 
 
20
using GLib;
 
21
 
 
22
void setup_gsettings()
 
23
{
 
24
  var dir = Environment.get_variable("DEJA_DUP_TEST_HOME");
 
25
 
 
26
  var schema_dir = Path.build_filename(dir, "share", "glib-2.0", "schemas");
 
27
  DirUtils.create_with_parents(schema_dir, 0700);
 
28
 
 
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);
 
31
 
 
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);
 
34
 
 
35
  if (Posix.system("glib-compile-schemas %s".printf(schema_dir)) != 0)
 
36
    warning("Could not compile schemas in %s", schema_dir);
 
37
 
 
38
  Environment.set_variable("GSETTINGS_BACKEND", "memory", true);
 
39
}
 
40
 
 
41
void backup_setup()
 
42
{
 
43
  var dir = Environment.get_variable("DEJA_DUP_TEST_HOME");
 
44
 
 
45
  var cachedir = Path.build_filename(dir, "cache");
 
46
  DirUtils.create_with_parents(Path.build_filename(cachedir, "deja-dup"), 0700);
 
47
 
 
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);
 
52
 
 
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");
 
57
}
 
58
 
 
59
void backup_teardown()
 
60
{
 
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);
 
65
  }
 
66
 
 
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");
 
71
  }
 
72
 
 
73
  file = File.new_for_path("/tmp/not/a/thing");
 
74
  if (file.query_exists(null)) {
 
75
    try {
 
76
      file.delete(null);
 
77
    }
 
78
    catch (Error e) {
 
79
      assert_not_reached();
 
80
    }
 
81
  }
 
82
 
 
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"));
 
85
 
 
86
  Environment.unset_variable("DEJA_DUP_TEST_MOCKSCRIPT");
 
87
  Environment.unset_variable("XDG_CACHE_HOME");
 
88
}
 
89
 
 
90
public enum Mode {
 
91
  NONE,
 
92
  STATUS,
 
93
  DRY,
 
94
  BACKUP,
 
95
  CLEANUP,
 
96
  RESTORE,
 
97
  RESTORE_STATUS,
 
98
  LIST,
 
99
}
 
100
 
 
101
public string default_args(Mode mode = Mode.NONE, bool encrypted = false, string extra = "")
 
102
{
 
103
  var cachedir = Environment.get_variable("XDG_CACHE_HOME");
 
104
 
 
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);
 
111
 
 
112
  string source_str = "";
 
113
  if (mode == Mode.DRY || mode == Mode.BACKUP)
 
114
    source_str = "--volsize=50 / ";
 
115
 
 
116
  string dry_str = "";
 
117
  if (mode == Mode.DRY)
 
118
    dry_str = "--dry-run ";
 
119
 
 
120
  string enc_str = "";
 
121
  if (!encrypted)
 
122
    enc_str = "--no-encryption ";
 
123
 
 
124
  string args = "";
 
125
 
 
126
  if (mode == Mode.STATUS || mode == Mode.RESTORE_STATUS)
 
127
    args += "collection-status ";
 
128
 
 
129
  if (mode == Mode.STATUS || mode == Mode.NONE || mode == Mode.DRY || mode == Mode.BACKUP) {
 
130
    args += "'--exclude=/tmp/not/a/thing' ";
 
131
 
 
132
    string[] excludes1 = {"~/Downloads", "~/.local/share/Trash", "~/.xsession-errors", "~/.thumbnails", "~/.Private", "~/.gvfs", "~/.adobe/Flash_Player/AssetCache"};
 
133
 
 
134
    var user = Environment.get_user_name();
 
135
    string[] excludes2 = {"/home/.ecryptfs/%s/.Private".printf(user), "/sys", "/proc", "/tmp"};
 
136
 
 
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);
 
141
    }
 
142
 
 
143
    args += "'--include=%s' ".printf(Environment.get_home_dir());
 
144
 
 
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);
 
149
    }
 
150
 
 
151
    args += "'--exclude=%s/deja-dup' '--exclude=%s' '--exclude=**' ".printf(cachedir, cachedir);
 
152
  }
 
153
 
 
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);
 
155
 
 
156
  return args;
 
157
}
 
158
 
 
159
class BackupRunner : Object
 
160
{
 
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;
 
170
 
 
171
  public void run()
 
172
  {
 
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);
 
176
      if (success != s)
 
177
        warning("Success didn't match; expected %d, got %d", (int) success, (int) s);
 
178
      if (cancelled != c)
 
179
        warning("Cancel didn't match; expected %d, got %d", (int) cancelled, (int) c);
 
180
      if (detail != d)
 
181
        warning("Detail didn't match; expected %s, got %s", detail, d);
 
182
      loop.quit();
 
183
    });
 
184
 
 
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);
 
191
      error_str = null;
 
192
      error_detail = null;
 
193
    });
 
194
    op.action_desc_changed.connect((action) => {
 
195
    });
 
196
    op.action_file_changed.connect((file, actual) => {
 
197
    });
 
198
    op.progress.connect((percent) => {
 
199
    });
 
200
    op.passphrase_required.connect(() => {
 
201
      Test.message("Passphrase required");
 
202
    });
 
203
    op.question.connect((title, msg) => {
 
204
      Test.message("Question asked: %s, %s", title, msg);
 
205
    });
 
206
    op.is_full.connect((full) => {
 
207
      Test.message("Is full? %d", (int)full);
 
208
      if (is_full != full)
 
209
        warning("IsFull didn't match; expected %d, got %d", (int) is_full, (int) full);
 
210
    });
 
211
 
 
212
    op.start();
 
213
    if (callback != null) {
 
214
      Timeout.add_seconds(5, () => {
 
215
        callback(op);
 
216
        return false;
 
217
      });
 
218
    }
 
219
    loop.run();
 
220
 
 
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);
 
225
  }
 
226
}
 
227
 
 
228
void add_to_mockscript(string contents)
 
229
{
 
230
  var script = Environment.get_variable("DEJA_DUP_TEST_MOCKSCRIPT");
 
231
  string initial = "";
 
232
  try {
 
233
    FileUtils.get_contents(script, out initial, null);
 
234
    initial += "\n\n=== deja-dup ===";
 
235
  }
 
236
  catch (Error e) {
 
237
    initial = "";
 
238
  }
 
239
 
 
240
  var real_contents = initial + "\n" + contents;
 
241
  try {
 
242
    FileUtils.set_contents(script, real_contents);
 
243
  }
 
244
  catch (Error e) {
 
245
    assert_not_reached();
 
246
  }
 
247
}
 
248
 
 
249
string replace_keywords(string in)
 
250
{
 
251
  var home = Environment.get_home_dir();
 
252
  return in.replace("@HOME@", home);
 
253
}
 
254
 
 
255
void process_operation_block(KeyFile keyfile, string group, BackupRunner br) throws Error
 
256
{
 
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");
 
262
  else
 
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");
 
276
}
 
277
 
 
278
void process_duplicity_run_block(KeyFile keyfile, string run, BackupRunner br) throws Error
 
279
{
 
280
  string outputscript = null;
 
281
  string extra_args = "";
 
282
  bool encrypted = false;
 
283
  bool cancel = false;
 
284
  bool stop = false;
 
285
  Mode mode = Mode.NONE;
 
286
 
 
287
  var parts = run.split(" ", 2);
 
288
  var type = parts[0];
 
289
  var group = "Duplicity " + run;
 
290
 
 
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(" "))
 
299
        extra_args += " ";
 
300
    }
 
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");
 
305
  }
 
306
 
 
307
  if (type == "status")
 
308
    mode = Mode.STATUS;
 
309
  else if (type == "status-restore")
 
310
    mode = Mode.RESTORE_STATUS; // should really consolidate the statuses
 
311
  else if (type == "dry")
 
312
    mode = Mode.DRY;
 
313
  else if (type == "list")
 
314
    mode = Mode.LIST;
 
315
  else if (type == "backup")
 
316
    mode = Mode.BACKUP;
 
317
  else if (type == "restore")
 
318
    mode = Mode.RESTORE;
 
319
  else if (type == "cleanup")
 
320
    mode = Mode.CLEANUP;
 
321
  else
 
322
    assert_not_reached();
 
323
 
 
324
  var dupscript = "ARGS: " + default_args(mode, encrypted, extra_args);
 
325
 
 
326
  if (cancel) {
 
327
    dupscript += "\n" + "DELAY: 10";
 
328
    br.callback = (op) => {
 
329
      op.cancel();
 
330
    };
 
331
  }
 
332
 
 
333
  if (stop) {
 
334
    dupscript += "\n" + "DELAY: 10";
 
335
    br.callback = (op) => {
 
336
      op.stop();
 
337
    };
 
338
  }
 
339
 
 
340
  if (outputscript != null && outputscript != "")
 
341
    dupscript += "\n\n" + outputscript + "\n";
 
342
 
 
343
  add_to_mockscript(dupscript);
 
344
}
 
345
 
 
346
void process_duplicity_block(KeyFile keyfile, string group, BackupRunner br) throws Error
 
347
{
 
348
  var runs = keyfile.get_string_list(group, "Runs");
 
349
  foreach (var run in runs)
 
350
    process_duplicity_run_block(keyfile, run, br);
 
351
}
 
352
 
 
353
void backup_run()
 
354
{
 
355
  try {
 
356
    var script = Environment.get_variable("DEJA_DUP_TEST_SCRIPT");
 
357
    var keyfile = new KeyFile();
 
358
    keyfile.load_from_file(script, KeyFileFlags.KEEP_COMMENTS);
 
359
 
 
360
    var br = new BackupRunner();
 
361
 
 
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);
 
368
    }
 
369
 
 
370
    br.run();
 
371
  }
 
372
  catch (Error e) {
 
373
    assert_not_reached();
 
374
  }
 
375
}
 
376
 
 
377
int main(string[] args)
 
378
{
 
379
  Test.init(ref args);
 
380
 
 
381
  var dir = "/tmp/deja-dup-test-XXXXXX";
 
382
  dir = DirUtils.mkdtemp(dir);
 
383
  Environment.set_variable("DEJA_DUP_TEST_HOME", dir, true);
 
384
 
 
385
  Environment.set_variable("DEJA_DUP_LANGUAGE", "en", true);
 
386
  Test.bug_base("https://launchpad.net/bugs/%s");
 
387
 
 
388
  setup_gsettings();
 
389
 
 
390
  var script = "unknown/unknown";
 
391
  if (args.length > 1)
 
392
    script = args[1];
 
393
  Environment.set_variable("DEJA_DUP_TEST_SCRIPT", script, true);
 
394
 
 
395
  var parts = script.split("/");
 
396
  var suitename = parts[parts.length - 2];
 
397
  var testname = parts[parts.length - 1].split(".")[0];
 
398
 
 
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);
 
402
 
 
403
  return Test.run();
 
404
}