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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
var { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
var { SessionWorker } = ChromeUtils.import(
"resource:///modules/sessionstore/SessionWorker.jsm"
);
var File = OS.File;
var Paths;
var SessionFile;
// We need a XULAppInfo to initialize SessionFile
ChromeUtils.import("resource://testing-common/AppInfo.jsm", this);
updateAppInfo({
name: "SessionRestoreTest",
ID: "{230de50e-4cd1-11dc-8314-0800200c9a66}",
version: "1",
platformVersion: "",
});
add_task(async function init() {
// Make sure that we have a profile before initializing SessionFile
let profd = do_get_profile();
SessionFile = ChromeUtils.import(
"resource:///modules/sessionstore/SessionFile.jsm",
{}
).SessionFile;
Paths = SessionFile.Paths;
let source = do_get_file("data/sessionstore_valid.js");
source.copyTo(profd, "sessionstore.js");
await writeCompressedFile(Paths.clean.replace("jsonlz4", "js"), Paths.clean);
// Finish initialization of SessionFile
await SessionFile.read();
});
var pathStore;
var pathBackup;
var decoder;
function promise_check_exist(path, shouldExist) {
return (async function() {
info(
"Ensuring that " + path + (shouldExist ? " exists" : " does not exist")
);
if ((await OS.File.exists(path)) != shouldExist) {
throw new Error(
"File " + path + " should " + (shouldExist ? "exist" : "not exist")
);
}
})();
}
function promise_check_contents(path, expect) {
return (async function() {
info("Checking whether " + path + " has the right contents");
let actual = await OS.File.read(path, {
encoding: "utf-8",
compression: "lz4",
});
Assert.deepEqual(
JSON.parse(actual),
expect,
`File ${path} contains the expected data.`
);
})();
}
function generateFileContents(id) {
let url = `http://example.com/test_backup_once#${id}_${Math.random()}`;
return { windows: [{ tabs: [{ entries: [{ url }], index: 1 }] }] };
}
// Write to the store, and check that it creates:
// - $Path.recovery with the new data
// - $Path.nextUpgradeBackup with the old data
add_task(async function test_first_write_backup() {
let initial_content = generateFileContents("initial");
let new_content = generateFileContents("test_1");
info("Before the first write, none of the files should exist");
await promise_check_exist(Paths.backups, false);
await File.makeDir(Paths.backups);
await File.writeAtomic(Paths.clean, JSON.stringify(initial_content), {
encoding: "utf-8",
compression: "lz4",
});
await SessionFile.write(new_content);
info("After first write, a few files should have been created");
await promise_check_exist(Paths.backups, true);
await promise_check_exist(Paths.clean, false);
await promise_check_exist(Paths.cleanBackup, true);
await promise_check_exist(Paths.recovery, true);
await promise_check_exist(Paths.recoveryBackup, false);
await promise_check_exist(Paths.nextUpgradeBackup, true);
await promise_check_contents(Paths.recovery, new_content);
await promise_check_contents(Paths.nextUpgradeBackup, initial_content);
});
// Write to the store again, and check that
// - $Path.clean is not written
// - $Path.recovery contains the new data
// - $Path.recoveryBackup contains the previous data
add_task(async function test_second_write_no_backup() {
let new_content = generateFileContents("test_2");
let previous_backup_content = await File.read(Paths.recovery, {
encoding: "utf-8",
compression: "lz4",
});
previous_backup_content = JSON.parse(previous_backup_content);
await OS.File.remove(Paths.cleanBackup);
await SessionFile.write(new_content);
await promise_check_exist(Paths.backups, true);
await promise_check_exist(Paths.clean, false);
await promise_check_exist(Paths.cleanBackup, false);
await promise_check_exist(Paths.recovery, true);
await promise_check_exist(Paths.nextUpgradeBackup, true);
await promise_check_contents(Paths.recovery, new_content);
await promise_check_contents(Paths.recoveryBackup, previous_backup_content);
});
// Make sure that we create $Paths.clean and remove $Paths.recovery*
// upon shutdown
add_task(async function test_shutdown() {
let output = generateFileContents("test_3");
await File.writeAtomic(Paths.recovery, "I should disappear");
await File.writeAtomic(Paths.recoveryBackup, "I should also disappear");
await SessionWorker.post("write", [
output,
{ isFinalWrite: true, performShutdownCleanup: true },
]);
Assert.equal(false, await File.exists(Paths.recovery));
Assert.equal(false, await File.exists(Paths.recoveryBackup));
await promise_check_contents(Paths.clean, output);
});
|