test_syncengine.js (8985B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 const { Service } = ChromeUtils.importESModule( 5 "resource://services-sync/service.sys.mjs" 6 ); 7 8 async function makeSteamEngine() { 9 let engine = new SyncEngine("Steam", Service); 10 await engine.initialize(); 11 return engine; 12 } 13 14 function guidSetOfSize(length) { 15 return new SerializableSet(Array.from({ length }, () => Utils.makeGUID())); 16 } 17 18 function assertSetsEqual(a, b) { 19 // Assert.deepEqual doesn't understand Set. 20 Assert.deepEqual(Array.from(a).sort(), Array.from(b).sort()); 21 } 22 23 async function testSteamEngineStorage(test) { 24 try { 25 let setupEngine = await makeSteamEngine(); 26 27 if (test.setup) { 28 await test.setup(setupEngine); 29 } 30 31 // Finalize the engine to flush the backlog and previous failed to disk. 32 await setupEngine.finalize(); 33 34 if (test.beforeCheck) { 35 await test.beforeCheck(); 36 } 37 38 let checkEngine = await makeSteamEngine(); 39 await test.check(checkEngine); 40 41 await checkEngine.resetClient(); 42 await checkEngine.finalize(); 43 } finally { 44 for (const pref of Svc.PrefBranch.getChildList("")) { 45 Svc.PrefBranch.clearUserPref(pref); 46 } 47 } 48 } 49 50 let server; 51 52 add_task(async function setup() { 53 server = httpd_setup({}); 54 }); 55 56 add_task(async function test_url_attributes() { 57 _("SyncEngine url attributes"); 58 await SyncTestingInfrastructure(server); 59 Service.clusterURL = "https://cluster/1.1/foo/"; 60 let engine = await makeSteamEngine(); 61 try { 62 Assert.equal(engine.storageURL, "https://cluster/1.1/foo/storage/"); 63 Assert.equal(engine.engineURL, "https://cluster/1.1/foo/storage/steam"); 64 Assert.equal(engine.metaURL, "https://cluster/1.1/foo/storage/meta/global"); 65 } finally { 66 for (const pref of Svc.PrefBranch.getChildList("")) { 67 Svc.PrefBranch.clearUserPref(pref); 68 } 69 } 70 }); 71 72 add_task(async function test_syncID() { 73 _("SyncEngine.syncID corresponds to preference"); 74 await SyncTestingInfrastructure(server); 75 let engine = await makeSteamEngine(); 76 try { 77 // Ensure pristine environment 78 Assert.equal( 79 Svc.PrefBranch.getPrefType("steam.syncID"), 80 Ci.nsIPrefBranch.PREF_INVALID 81 ); 82 Assert.equal(await engine.getSyncID(), ""); 83 84 // Performing the first get on the attribute will generate a new GUID. 85 Assert.equal(await engine.resetLocalSyncID(), "fake-guid-00"); 86 Assert.equal(Svc.PrefBranch.getStringPref("steam.syncID"), "fake-guid-00"); 87 88 Svc.PrefBranch.setStringPref("steam.syncID", Utils.makeGUID()); 89 Assert.equal(Svc.PrefBranch.getStringPref("steam.syncID"), "fake-guid-01"); 90 Assert.equal(await engine.getSyncID(), "fake-guid-01"); 91 } finally { 92 for (const pref of Svc.PrefBranch.getChildList("")) { 93 Svc.PrefBranch.clearUserPref(pref); 94 } 95 } 96 }); 97 98 add_task(async function test_lastSync() { 99 _("SyncEngine.lastSync corresponds to preferences"); 100 await SyncTestingInfrastructure(server); 101 let engine = await makeSteamEngine(); 102 try { 103 // Ensure pristine environment 104 Assert.equal( 105 Svc.PrefBranch.getPrefType("steam.lastSync"), 106 Ci.nsIPrefBranch.PREF_INVALID 107 ); 108 Assert.equal(await engine.getLastSync(), 0); 109 110 // Floats are properly stored as floats and synced with the preference 111 await engine.setLastSync(123.45); 112 Assert.equal(await engine.getLastSync(), 123.45); 113 Assert.equal(Svc.PrefBranch.getStringPref("steam.lastSync"), "123.45"); 114 115 // Integer is properly stored 116 await engine.setLastSync(67890); 117 Assert.equal(await engine.getLastSync(), 67890); 118 Assert.equal(Svc.PrefBranch.getStringPref("steam.lastSync"), "67890"); 119 120 // resetLastSync() resets the value (and preference) to 0 121 await engine.resetLastSync(); 122 Assert.equal(await engine.getLastSync(), 0); 123 Assert.equal(Svc.PrefBranch.getStringPref("steam.lastSync"), "0"); 124 } finally { 125 for (const pref of Svc.PrefBranch.getChildList("")) { 126 Svc.PrefBranch.clearUserPref(pref); 127 } 128 } 129 }); 130 131 add_task(async function test_toFetch() { 132 _("SyncEngine.toFetch corresponds to file on disk"); 133 await SyncTestingInfrastructure(server); 134 135 await testSteamEngineStorage({ 136 toFetch: guidSetOfSize(3), 137 setup(engine) { 138 // Ensure pristine environment 139 Assert.equal(engine.toFetch.size, 0); 140 141 // Write file to disk 142 engine.toFetch = this.toFetch; 143 Assert.equal(engine.toFetch, this.toFetch); 144 }, 145 check(engine) { 146 // toFetch is written asynchronously 147 assertSetsEqual(engine.toFetch, this.toFetch); 148 }, 149 }); 150 151 await testSteamEngineStorage({ 152 toFetch: guidSetOfSize(4), 153 toFetch2: guidSetOfSize(5), 154 setup(engine) { 155 // Make sure it work for consecutive writes before the callback is executed. 156 engine.toFetch = this.toFetch; 157 Assert.equal(engine.toFetch, this.toFetch); 158 159 engine.toFetch = this.toFetch2; 160 Assert.equal(engine.toFetch, this.toFetch2); 161 }, 162 check(engine) { 163 assertSetsEqual(engine.toFetch, this.toFetch2); 164 }, 165 }); 166 167 await testSteamEngineStorage({ 168 toFetch: guidSetOfSize(2), 169 async beforeCheck() { 170 let toFetchPath = PathUtils.join( 171 PathUtils.profileDir, 172 "weave", 173 "toFetch", 174 "steam.json" 175 ); 176 await IOUtils.writeJSON(toFetchPath, this.toFetch, { 177 tmpPath: toFetchPath + ".tmp", 178 }); 179 }, 180 check(engine) { 181 // Read file from disk 182 assertSetsEqual(engine.toFetch, this.toFetch); 183 }, 184 }); 185 }); 186 187 add_task(async function test_previousFailed() { 188 _("SyncEngine.previousFailed corresponds to file on disk"); 189 await SyncTestingInfrastructure(server); 190 191 await testSteamEngineStorage({ 192 previousFailed: guidSetOfSize(3), 193 setup(engine) { 194 // Ensure pristine environment 195 Assert.equal(engine.previousFailed.size, 0); 196 197 // Write file to disk 198 engine.previousFailed = this.previousFailed; 199 Assert.equal(engine.previousFailed, this.previousFailed); 200 }, 201 check(engine) { 202 // previousFailed is written asynchronously 203 assertSetsEqual(engine.previousFailed, this.previousFailed); 204 }, 205 }); 206 207 await testSteamEngineStorage({ 208 previousFailed: guidSetOfSize(4), 209 previousFailed2: guidSetOfSize(5), 210 setup(engine) { 211 // Make sure it work for consecutive writes before the callback is executed. 212 engine.previousFailed = this.previousFailed; 213 Assert.equal(engine.previousFailed, this.previousFailed); 214 215 engine.previousFailed = this.previousFailed2; 216 Assert.equal(engine.previousFailed, this.previousFailed2); 217 }, 218 check(engine) { 219 assertSetsEqual(engine.previousFailed, this.previousFailed2); 220 }, 221 }); 222 223 await testSteamEngineStorage({ 224 previousFailed: guidSetOfSize(2), 225 async beforeCheck() { 226 let previousFailedPath = PathUtils.join( 227 PathUtils.profileDir, 228 "weave", 229 "failed", 230 "steam.json" 231 ); 232 await IOUtils.writeJSON(previousFailedPath, this.previousFailed, { 233 tmpPath: previousFailedPath + ".tmp", 234 }); 235 }, 236 check(engine) { 237 // Read file from disk 238 assertSetsEqual(engine.previousFailed, this.previousFailed); 239 }, 240 }); 241 }); 242 243 add_task(async function test_resetClient() { 244 _("SyncEngine.resetClient resets lastSync and toFetch"); 245 await SyncTestingInfrastructure(server); 246 let engine = await makeSteamEngine(); 247 try { 248 // Ensure pristine environment 249 Assert.equal( 250 Svc.PrefBranch.getPrefType("steam.lastSync"), 251 Ci.nsIPrefBranch.PREF_INVALID 252 ); 253 Assert.equal(engine.toFetch.size, 0); 254 255 await engine.setLastSync(123.45); 256 engine.toFetch = guidSetOfSize(4); 257 engine.previousFailed = guidSetOfSize(3); 258 259 await engine.resetClient(); 260 Assert.equal(await engine.getLastSync(), 0); 261 Assert.equal(engine.toFetch.size, 0); 262 Assert.equal(engine.previousFailed.size, 0); 263 } finally { 264 for (const pref of Svc.PrefBranch.getChildList("")) { 265 Svc.PrefBranch.clearUserPref(pref); 266 } 267 } 268 }); 269 270 add_task(async function test_wipeServer() { 271 _("SyncEngine.wipeServer deletes server data and resets the client."); 272 let engine = await makeSteamEngine(); 273 274 const PAYLOAD = 42; 275 let steamCollection = new ServerWBO("steam", PAYLOAD); 276 let steamServer = httpd_setup({ 277 "/1.1/foo/storage/steam": steamCollection.handler(), 278 }); 279 await SyncTestingInfrastructure(steamServer); 280 do_test_pending(); 281 282 try { 283 // Some data to reset. 284 await engine.setLastSync(123.45); 285 engine.toFetch = guidSetOfSize(3); 286 287 _("Wipe server data and reset client."); 288 await engine.wipeServer(); 289 Assert.equal(steamCollection.payload, undefined); 290 Assert.equal(await engine.getLastSync(), 0); 291 Assert.equal(engine.toFetch.size, 0); 292 } finally { 293 steamServer.stop(do_test_finished); 294 for (const pref of Svc.PrefBranch.getChildList("")) { 295 Svc.PrefBranch.clearUserPref(pref); 296 } 297 } 298 }); 299 300 add_task(async function finish() { 301 await promiseStopServer(server); 302 });