test_CookiesBackupResource.js (7576B)
1 /* Any copyright is dedicated to the Public Domain. 2 https://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 const { CookiesBackupResource } = ChromeUtils.importESModule( 7 "resource:///modules/backup/CookiesBackupResource.sys.mjs" 8 ); 9 10 /** 11 * Tests that we can measure the Cookies db in a profile directory. 12 */ 13 add_task(async function test_measure() { 14 const EXPECTED_COOKIES_DB_SIZE = 1230; 15 16 Services.fog.testResetFOG(); 17 18 // Create resource files in temporary directory 19 let tempDir = PathUtils.tempDir; 20 let tempCookiesDBPath = PathUtils.join(tempDir, "cookies.sqlite"); 21 await createKilobyteSizedFile(tempCookiesDBPath, EXPECTED_COOKIES_DB_SIZE); 22 23 let cookiesBackupResource = new CookiesBackupResource(); 24 await cookiesBackupResource.measure(tempDir); 25 26 let cookiesMeasurement = Glean.browserBackup.cookiesSize.testGetValue(); 27 let scalars = TelemetryTestUtils.getProcessScalars("parent", false, false); 28 29 // Compare glean vs telemetry measurements 30 TelemetryTestUtils.assertScalar( 31 scalars, 32 "browser.backup.cookies_size", 33 cookiesMeasurement, 34 "Glean and telemetry measurements for cookies.sqlite should be equal" 35 ); 36 37 // Compare glean measurements vs actual file sizes 38 Assert.equal( 39 cookiesMeasurement, 40 EXPECTED_COOKIES_DB_SIZE, 41 "Should have collected the correct glean measurement for cookies.sqlite" 42 ); 43 44 await maybeRemovePath(tempCookiesDBPath); 45 }); 46 47 /** 48 * Test that the backup method correctly copies items from the profile directory 49 * into the staging directory. 50 */ 51 add_task(async function test_backup() { 52 let sandbox = sinon.createSandbox(); 53 54 let cookiesBackupResource = new CookiesBackupResource(); 55 let sourcePath = await IOUtils.createUniqueDirectory( 56 PathUtils.tempDir, 57 "CookiesBackupResource-source-test" 58 ); 59 let stagingPath = await IOUtils.createUniqueDirectory( 60 PathUtils.tempDir, 61 "CookiesBackupResource-staging-test" 62 ); 63 64 // Make sure this file exists in the source directory, otherwise 65 // BackupResource will skip attempting to back it up. 66 await createTestFiles(sourcePath, [{ path: "cookies.sqlite" }]); 67 68 // We have no need to test that Sqlite.sys.mjs's backup method is working - 69 // this is something that is tested in Sqlite's own tests. We can just make 70 // sure that it's being called using sinon. Unfortunately, we cannot do the 71 // same thing with IOUtils.copy, as its methods are not stubbable. 72 let fakeConnection = { 73 backup: sandbox.stub().resolves(true), 74 close: sandbox.stub().resolves(true), 75 }; 76 sandbox.stub(Sqlite, "openConnection").returns(fakeConnection); 77 78 let manifestEntry = await cookiesBackupResource.backup( 79 stagingPath, 80 sourcePath 81 ); 82 Assert.equal( 83 manifestEntry, 84 null, 85 "CookiesBackupResource.backup should return null as its ManifestEntry" 86 ); 87 88 // Next, we'll make sure that the Sqlite connection had `backup` called on it 89 // with the right arguments. 90 Assert.ok( 91 fakeConnection.backup.calledOnce, 92 "Called backup the expected number of times for all connections" 93 ); 94 Assert.ok( 95 fakeConnection.backup.calledWith( 96 PathUtils.join(stagingPath, "cookies.sqlite") 97 ), 98 "Called backup on the cookies.sqlite Sqlite connection" 99 ); 100 101 await maybeRemovePath(stagingPath); 102 await maybeRemovePath(sourcePath); 103 104 sandbox.restore(); 105 }); 106 107 /** 108 * Tests that the backup method does not copy the cookie database if the 109 * browser is configured to not save history - either while running, or to 110 * clear it at shutdown. 111 */ 112 add_task(async function test_backup_no_saved_history() { 113 let cookiesBackupResource = new CookiesBackupResource(); 114 let sourcePath = await IOUtils.createUniqueDirectory( 115 PathUtils.tempDir, 116 "CookiesBackupResource-source-test" 117 ); 118 let stagingPath = await IOUtils.createUniqueDirectory( 119 PathUtils.tempDir, 120 "CookiesBackupResource-staging-test" 121 ); 122 123 let sandbox = sinon.createSandbox(); 124 let fakeConnection = { 125 backup: sandbox.stub().resolves(true), 126 close: sandbox.stub().resolves(true), 127 }; 128 sandbox.stub(Sqlite, "openConnection").returns(fakeConnection); 129 130 // First, we'll try with browsing history in general being disabled. 131 Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, false); 132 Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, false); 133 134 Assert.ok( 135 !CookiesBackupResource.canBackupResource, 136 "Should not be able to backup cookies" 137 ); 138 139 // Now verify that the sanitize shutdown pref also prevents us from backing 140 // up cookies 141 Services.prefs.setBoolPref(HISTORY_ENABLED_PREF, true); 142 Services.prefs.setBoolPref(SANITIZE_ON_SHUTDOWN_PREF, true); 143 144 fakeConnection.backup.resetHistory(); 145 let manifestEntry = await cookiesBackupResource.backup( 146 stagingPath, 147 sourcePath 148 ); 149 Assert.deepEqual( 150 manifestEntry, 151 null, 152 "Should have gotten back a null ManifestEntry" 153 ); 154 155 Assert.ok( 156 fakeConnection.backup.notCalled, 157 "No sqlite connections should have been made with sanitize shutdown enabled" 158 ); 159 160 await maybeRemovePath(stagingPath); 161 await maybeRemovePath(sourcePath); 162 163 sandbox.restore(); 164 Services.prefs.clearUserPref(HISTORY_ENABLED_PREF); 165 Services.prefs.clearUserPref(SANITIZE_ON_SHUTDOWN_PREF); 166 }); 167 168 /** 169 * Tests that the backup method correctly skips backing up cookies when 170 * permanent private browsing mode is enabled. 171 */ 172 add_task(async function test_backup_private_browsing() { 173 let sandbox = sinon.createSandbox(); 174 175 let cookiesBackupResource = new CookiesBackupResource(); 176 let sourcePath = await IOUtils.createUniqueDirectory( 177 PathUtils.tempDir, 178 "CookiesBackupResource-source-test" 179 ); 180 let stagingPath = await IOUtils.createUniqueDirectory( 181 PathUtils.tempDir, 182 "CookiesBackupResource-staging-test" 183 ); 184 185 let fakeConnection = { 186 backup: sandbox.stub().resolves(true), 187 close: sandbox.stub().resolves(true), 188 }; 189 sandbox.stub(Sqlite, "openConnection").returns(fakeConnection); 190 sandbox.stub(PrivateBrowsingUtils, "permanentPrivateBrowsing").value(true); 191 192 let manifestEntry = await cookiesBackupResource.backup( 193 stagingPath, 194 sourcePath 195 ); 196 Assert.deepEqual( 197 manifestEntry, 198 null, 199 "Should have gotten back a null ManifestEntry" 200 ); 201 202 Assert.ok( 203 fakeConnection.backup.notCalled, 204 "No sqlite connections should have been made with permanent private browsing enabled" 205 ); 206 207 await maybeRemovePath(stagingPath); 208 await maybeRemovePath(sourcePath); 209 210 sandbox.restore(); 211 }); 212 213 /** 214 * Test that the recover method correctly copies items from the recovery 215 * directory into the destination profile directory. 216 */ 217 add_task(async function test_recover() { 218 let cookiesBackupResource = new CookiesBackupResource(); 219 let recoveryPath = await IOUtils.createUniqueDirectory( 220 PathUtils.tempDir, 221 "CookiesBackupResource-recovery-test" 222 ); 223 let destProfilePath = await IOUtils.createUniqueDirectory( 224 PathUtils.tempDir, 225 "CookiesBackupResource-test-profile" 226 ); 227 228 const simpleCopyFiles = [{ path: "cookies.sqlite" }]; 229 await createTestFiles(recoveryPath, simpleCopyFiles); 230 231 // The backup method is expected to have returned a null ManifestEntry 232 let postRecoveryEntry = await cookiesBackupResource.recover( 233 null /* manifestEntry */, 234 recoveryPath, 235 destProfilePath 236 ); 237 Assert.equal( 238 postRecoveryEntry, 239 null, 240 "CookiesBackupResource.recover should return null as its post " + 241 "recovery entry" 242 ); 243 244 await assertFilesExist(destProfilePath, simpleCopyFiles); 245 246 await maybeRemovePath(recoveryPath); 247 await maybeRemovePath(destProfilePath); 248 });