test_action-import-snapshot-and-census.js (3820B)
1 /* Any copyright is dedicated to the Public Domain. 2 http://creativecommons.org/publicdomain/zero/1.0/ */ 3 4 "use strict"; 5 6 /** 7 * Tests the task creator `importSnapshotAndCensus()` for the whole flow of 8 * importing a snapshot, and its sub-actions. 9 */ 10 11 const { 12 actions, 13 snapshotState: states, 14 treeMapState, 15 } = require("resource://devtools/client/memory/constants.js"); 16 const { 17 exportSnapshot, 18 importSnapshotAndCensus, 19 } = require("resource://devtools/client/memory/actions/io.js"); 20 const { 21 takeSnapshotAndCensus, 22 } = require("resource://devtools/client/memory/actions/snapshot.js"); 23 24 add_task(async function () { 25 const front = new StubbedMemoryFront(); 26 const heapWorker = new HeapAnalysesClient(); 27 await front.attach(); 28 const store = Store(); 29 const { subscribe, dispatch, getState } = store; 30 31 const destPath = await createTempFile(); 32 dispatch(takeSnapshotAndCensus(front, heapWorker)); 33 await waitUntilCensusState(store, s => s.treeMap, [treeMapState.SAVED]); 34 35 const exportEvents = Promise.all([ 36 waitForDispatch(store, actions.EXPORT_SNAPSHOT_START), 37 waitForDispatch(store, actions.EXPORT_SNAPSHOT_END), 38 ]); 39 dispatch(exportSnapshot(getState().snapshots[0], destPath)); 40 await exportEvents; 41 42 // Now import our freshly exported snapshot 43 let snapshotI = 0; 44 let censusI = 0; 45 const snapshotStates = ["IMPORTING", "READING", "READ"]; 46 const censusStates = ["SAVING", "SAVED"]; 47 const expectStates = () => { 48 const snapshot = getState().snapshots[1]; 49 if (!snapshot) { 50 return; 51 } 52 if (snapshotI < snapshotStates.length) { 53 const isCorrectState = 54 snapshot.state === states[snapshotStates[snapshotI]]; 55 if (isCorrectState) { 56 ok(true, `Found expected snapshot state ${snapshotStates[snapshotI]}`); 57 snapshotI++; 58 } 59 } 60 if (snapshot.treeMap && censusI < censusStates.length) { 61 if (snapshot.treeMap.state === treeMapState[censusStates[censusI]]) { 62 ok(true, `Found expected census state ${censusStates[censusI]}`); 63 censusI++; 64 } 65 } 66 }; 67 68 const unsubscribe = subscribe(expectStates); 69 dispatch(importSnapshotAndCensus(heapWorker, destPath)); 70 71 await waitUntilState(store, () => { 72 return ( 73 snapshotI === snapshotStates.length && censusI === censusStates.length 74 ); 75 }); 76 unsubscribe(); 77 equal( 78 snapshotI, 79 snapshotStates.length, 80 "importSnapshotAndCensus() produces the correct sequence of states in a snapshot" 81 ); 82 equal( 83 getState().snapshots[1].state, 84 states.READ, 85 "imported snapshot is in READ state" 86 ); 87 equal( 88 censusI, 89 censusStates.length, 90 "importSnapshotAndCensus() produces the correct sequence of states in a census" 91 ); 92 equal( 93 getState().snapshots[1].treeMap.state, 94 treeMapState.SAVED, 95 "imported snapshot is in READ state" 96 ); 97 ok(getState().snapshots[1].selected, "imported snapshot is selected"); 98 99 // Check snapshot data 100 const snapshot1 = getState().snapshots[0]; 101 const snapshot2 = getState().snapshots[1]; 102 103 equal( 104 snapshot1.treeMap.display, 105 snapshot2.treeMap.display, 106 "imported snapshot has correct display" 107 ); 108 109 // Clone the census data so we can destructively remove the ID/parents to compare 110 // equal census data 111 const census1 = stripUnique( 112 JSON.parse(JSON.stringify(snapshot1.treeMap.report)) 113 ); 114 const census2 = stripUnique( 115 JSON.parse(JSON.stringify(snapshot2.treeMap.report)) 116 ); 117 118 equal( 119 JSON.stringify(census1), 120 JSON.stringify(census2), 121 "Imported snapshot has correct census" 122 ); 123 124 function stripUnique(obj) { 125 const children = obj.children || []; 126 for (const child of children) { 127 delete child.id; 128 delete child.parent; 129 stripUnique(child); 130 } 131 delete obj.id; 132 delete obj.parent; 133 return obj; 134 } 135 });