1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
Cu.import("resource://gre/modules/Services.jsm", this);
Cu.import("resource://gre/modules/osfile.jsm", this);
Cu.import("resource://gre/modules/Task.jsm", this);
Cu.import("resource://gre/modules/Preferences.jsm", this);
const Paths = SessionFile.Paths;
const PREF_UPGRADE = "browser.sessionstore.upgradeBackup.latestBuildID";
const PREF_MAX_UPGRADE_BACKUPS = "browser.sessionstore.upgradeBackup.maxUpgradeBackups";
/**
* Prepares tests by retrieving the current platform's build ID, clearing the
* build where the last backup was created and creating arbitrary JSON data
* for a new backup.
*/
var prepareTest = Task.async(function* () {
let result = {};
result.buildID = Services.appinfo.platformBuildID;
Services.prefs.setCharPref(PREF_UPGRADE, "");
result.contents = JSON.stringify({"browser_upgrade_backup.js": Math.random()});
return result;
});
/**
* Retrieves all upgrade backups and returns them in an array.
*/
var getUpgradeBackups = Task.async(function* () {
let iterator;
let backups = [];
let upgradeBackupPrefix = Paths.upgradeBackupPrefix;
try {
iterator = new OS.File.DirectoryIterator(Paths.backups);
// iterate over all files in the backup directory
yield iterator.forEach(function (file) {
// check the upgradeBackupPrefix
if (file.path.startsWith(Paths.upgradeBackupPrefix)) {
// the file is a backup
backups.push(file.path);
}
}, this);
} finally {
if (iterator) {
iterator.close();
}
}
// return results
return backups;
});
add_task(function* init() {
// Wait until initialization is complete
yield SessionStore.promiseInitialized;
yield SessionFile.wipe();
});
add_task(function* test_upgrade_backup() {
let test = yield prepareTest();
info("Let's check if we create an upgrade backup");
yield OS.File.writeAtomic(Paths.clean, test.contents);
yield SessionFile.read(); // First call to read() initializes the SessionWorker
yield SessionFile.write(""); // First call to write() triggers the backup
is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
is((yield OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
let data = yield OS.File.read(Paths.upgradeBackup);
is(test.contents, (new TextDecoder()).decode(data), "upgrade backup contains the expected contents");
info("Let's check that we don't overwrite this upgrade backup");
let newContents = JSON.stringify({"something else entirely": Math.random()});
yield OS.File.writeAtomic(Paths.clean, newContents);
yield SessionFile.read(); // Reinitialize the SessionWorker
yield SessionFile.write(""); // Next call to write() shouldn't trigger the backup
data = yield OS.File.read(Paths.upgradeBackup);
is(test.contents, (new TextDecoder()).decode(data), "upgrade backup hasn't changed");
});
add_task(function* test_upgrade_backup_removal() {
let test = yield prepareTest();
let maxUpgradeBackups = Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3);
info("Let's see if we remove backups if there are too many");
yield OS.File.writeAtomic(Paths.clean, test.contents);
// if the nextUpgradeBackup already exists (from another test), remove it
if (OS.File.exists(Paths.nextUpgradeBackup)) {
yield OS.File.remove(Paths.nextUpgradeBackup);
}
// create dummy backups
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20080101010101", "");
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20090101010101", "");
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20100101010101", "");
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20110101010101", "");
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20120101010101", "");
yield OS.File.writeAtomic(Paths.upgradeBackupPrefix + "20130101010101", "");
// get currently existing backups
let backups = yield getUpgradeBackups();
// trigger new backup
yield SessionFile.read(); // First call to read() initializes the SessionWorker
yield SessionFile.write(""); // First call to write() triggers the backup and the cleanup
// a new backup should have been created (and still exist)
is(Services.prefs.getCharPref(PREF_UPGRADE), test.buildID, "upgrade backup should be set");
is((yield OS.File.exists(Paths.upgradeBackup)), true, "upgrade backup file has been created");
// get currently existing backups and check their count
let newBackups = yield getUpgradeBackups();
is(newBackups.length, maxUpgradeBackups, "expected number of backups are present after removing old backups");
// find all backups that were created during the last call to `SessionFile.write("");`
// ie, filter out all the backups that have already been present before the call
newBackups = newBackups.filter(function (backup) {
return backups.indexOf(backup) < 0;
});
// check that exactly one new backup was created
is(newBackups.length, 1, "one new backup was created that was not removed");
yield SessionFile.write(""); // Second call to write() should not trigger anything
backups = yield getUpgradeBackups();
is(backups.length, maxUpgradeBackups, "second call to SessionFile.write() didn't create or remove more backups");
});
|