forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			449 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			449 lines
		
	
	
	
		
			11 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|  * http://creativecommons.org/publicdomain/zero/1.0/
 | |
|  */
 | |
| "use strict";
 | |
| 
 | |
| const { TabUnloader } = ChromeUtils.import(
 | |
|   "resource:///modules/TabUnloader.jsm"
 | |
| );
 | |
| 
 | |
| let TestTabUnloaderMethods = {
 | |
|   isNonDiscardable(tab, weight) {
 | |
|     return /\bselected\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   isParentProcess(tab, weight) {
 | |
|     return /\bparent\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   isPinned(tab, weight) {
 | |
|     return /\bpinned\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   isLoading(tab, weight) {
 | |
|     return /\bloading\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   usingPictureInPicture(tab, weight) {
 | |
|     return /\bpictureinpicture\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   playingMedia(tab, weight) {
 | |
|     return /\bmedia\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   usingWebRTC(tab, weight) {
 | |
|     return /\bwebrtc\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   isPrivate(tab, weight) {
 | |
|     return /\bprivate\b/.test(tab.keywords) ? weight : 0;
 | |
|   },
 | |
| 
 | |
|   getMinTabCount() {
 | |
|     // Use a low number for testing.
 | |
|     return 3;
 | |
|   },
 | |
| 
 | |
|   getNow() {
 | |
|     return 100;
 | |
|   },
 | |
| 
 | |
|   *iterateProcesses(tab) {
 | |
|     for (let process of tab.process.split(",")) {
 | |
|       yield Number(process);
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   async calculateMemoryUsage(processMap, tabs) {
 | |
|     let memory = tabs[0].memory;
 | |
|     for (let pid of processMap.keys()) {
 | |
|       processMap.get(pid).memory = memory ? memory[pid - 1] : 1;
 | |
|     }
 | |
|   },
 | |
| };
 | |
| 
 | |
| let unloadTests = [
 | |
|   // Each item in the array represents one test. The test is a subarray
 | |
|   // containing an element per tab. This is a string of keywords that
 | |
|   // identify which criteria apply. The first part of the string may contain
 | |
|   // a number that represents the last visit time, where higher numbers
 | |
|   // are later. The last element in the subarray is special and identifies
 | |
|   // the expected order of the tabs sorted by weight. The first tab in
 | |
|   // this list is the one that is expected to selected to be discarded.
 | |
|   { tabs: ["1 selected", "2", "3"], result: "1,2,0" },
 | |
|   { tabs: ["1", "2 selected", "3"], result: "0,2,1" },
 | |
|   { tabs: ["1 selected", "2", "3"], process: ["1", "2", "3"], result: "1,2,0" },
 | |
|   {
 | |
|     tabs: ["1 selected", "2 selected", "3 selected"],
 | |
|     process: ["1", "2", "3"],
 | |
|     result: "0,1,2",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1 selected", "2", "3"],
 | |
|     process: ["1,2,3", "2", "3"],
 | |
|     result: "1,2,0",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["9", "8", "6", "5 selected", "2", "3", "4", "1"],
 | |
|     result: "7,4,5,6,2,1,0,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["9", "8 pinned", "6", "5 selected", "2", "3 pinned", "4", "1"],
 | |
|     result: "7,4,6,2,0,5,1,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: [
 | |
|       "9",
 | |
|       "8 pinned",
 | |
|       "6",
 | |
|       "5 selected pinned",
 | |
|       "2",
 | |
|       "3 pinned",
 | |
|       "4",
 | |
|       "1",
 | |
|     ],
 | |
|     result: "7,4,6,2,0,5,1,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: [
 | |
|       "9",
 | |
|       "8 pinned",
 | |
|       "6",
 | |
|       "5 selected pinned",
 | |
|       "2",
 | |
|       "3 selected pinned",
 | |
|       "4",
 | |
|       "1",
 | |
|     ],
 | |
|     result: "7,4,6,2,0,1,5,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 selected", "3", "4 media", "5", "6"],
 | |
|     result: "0,2,4,5,1,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1 media", "2 selected media", "3", "4 media", "5", "6"],
 | |
|     result: "2,4,5,0,3,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1 media", "2 media pinned", "3", "4 media", "5 pinned", "6"],
 | |
|     result: "2,5,4,0,3,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: [
 | |
|       "1 media",
 | |
|       "2 media pinned",
 | |
|       "3",
 | |
|       "4 media",
 | |
|       "5 media pinned",
 | |
|       "6 selected",
 | |
|     ],
 | |
|     result: "2,0,3,5,1,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: [
 | |
|       "10 selected",
 | |
|       "20 private",
 | |
|       "30 webrtc",
 | |
|       "40 pictureinpicture",
 | |
|       "50 loading pinned",
 | |
|       "60",
 | |
|     ],
 | |
|     result: "5,4,0,1,2,3",
 | |
|   },
 | |
|   {
 | |
|     // Since TestTabUnloaderMethods.getNow() returns 100 and the test
 | |
|     // passes minInactiveDuration = 0 to TabUnloader.getSortedTabs(),
 | |
|     // tab 200 and 300 are excluded from the result.
 | |
|     tabs: ["300", "10", "50", "100", "200"],
 | |
|     result: "1,2,3",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "1", "1", "1", "1"],
 | |
|     result: "1,0,2,3,4,5",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 selected", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "1", "1", "1", "1"],
 | |
|     result: "0,2,3,4,5,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "2", "1", "1", "1"],
 | |
|     result: "0,1,2,3,4,5",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "3", "1", "1", "1"],
 | |
|     result: "1,0,2,3,4,5",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "3", "1", "1", "1"],
 | |
|     result: "2,0,3,4,5,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "3", "1", "1,2,3", "1"],
 | |
|     result: "0,2,3,4,5,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3", "4", "5", "6"],
 | |
|     process: ["1", "2", "3", "1", "1,4,5", "1"],
 | |
|     result: "2,0,3,4,5,1",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3 media", "4", "5 media", "6"],
 | |
|     process: ["1", "2", "3", "1", "1,4,5", "1"],
 | |
|     result: "0,3,5,1,2,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3 media", "4", "5 media", "6"],
 | |
|     process: ["1", "1", "3", "1", "1,4,5", "1"],
 | |
|     result: "0,3,5,1,2,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3 media", "4", "5 media", "6"],
 | |
|     process: ["1", "2", "3", "4", "1,4,5", "5"],
 | |
|     result: "0,3,5,1,2,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2 media", "3 media", "4", "5 media", "6"],
 | |
|     process: ["1", "1", "3", "4", "1,4,5", "5"],
 | |
|     result: "0,3,5,1,2,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1", "1", "1", "2", "1,3,4,5,6,7,8", "1"],
 | |
|     result: "0,1,2,3,4,5",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "2", "1,3,4,5,6,7,8", "1", "1", "1"],
 | |
|     result: "4,0,3,1,2,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 selected", "6"],
 | |
|     process: ["1", "1", "1", "2", "1,3,4,5,6,7,8", "1"],
 | |
|     result: "0,1,2,3,5,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6"],
 | |
|     process: ["1", "1", "1", "2", "1,3,4,5,6,7,8", "1"],
 | |
|     result: "0,1,2,3,5,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "2", "1,3,4,5,6,7,8", "1", "1", "1"],
 | |
|     result: "0,3,1,2,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1,3,4,5,6,7,8", "1", "1", "1", "1", "1", "1"],
 | |
|     result: "1,0,2,3,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1,3,4,5,6,7,8", "1", "1", "1", "1", "1"],
 | |
|     result: "2,0,1,3,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1,1,1,1,1,1,1", "1", "1", "1", "1,1,1,1,1", "1"],
 | |
|     result: "0,1,2,3,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1,2,3,4,5", "1", "1", "1", "1,2,3,4,5", "1"],
 | |
|     result: "0,1,2,3,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1,6", "1", "1", "1", "1,2,3,4,5", "1"],
 | |
|     result: "0,2,1,3,5,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1", "1", "1,6", "1,7", "1,8", "1,9", "1,2,3,4,5", "1"],
 | |
|     result: "2,3,0,5,1,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5 media", "6", "7", "8"],
 | |
|     process: ["1,10,11", "1", "1,2", "1,7", "1,8", "1,9", "1,2,3,4,5", "1"],
 | |
|     result: "0,3,1,5,2,6,7,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: [
 | |
|       "1 media",
 | |
|       "2 media",
 | |
|       "3 media",
 | |
|       "4 media",
 | |
|       "5 media",
 | |
|       "6",
 | |
|       "7",
 | |
|       "8",
 | |
|     ],
 | |
|     process: ["1,10,11", "1", "1,2", "1,7", "1,8", "1,9", "1,2,3,4,5", "1"],
 | |
|     result: "6,5,7,0,1,2,3,4",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3"],
 | |
|     process: ["1", "2", "3"],
 | |
|     memory: ["100", "200", "300"],
 | |
|     result: "0,1,2",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     process: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     memory: [
 | |
|       "100",
 | |
|       "200",
 | |
|       "300",
 | |
|       "400",
 | |
|       "500",
 | |
|       "600",
 | |
|       "700",
 | |
|       "800",
 | |
|       "900",
 | |
|       "1000",
 | |
|     ],
 | |
|     result: "0,1,2,3,4,5,6,7,8,9",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     process: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     memory: [
 | |
|       "100",
 | |
|       "900",
 | |
|       "300",
 | |
|       "500",
 | |
|       "400",
 | |
|       "700",
 | |
|       "600",
 | |
|       "1000",
 | |
|       "200",
 | |
|       "200",
 | |
|     ],
 | |
|     result: "1,0,2,3,5,4,6,7,8,9",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     process: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
 | |
|     memory: [
 | |
|       "1000",
 | |
|       "900",
 | |
|       "300",
 | |
|       "500",
 | |
|       "400",
 | |
|       "1000",
 | |
|       "600",
 | |
|       "1000",
 | |
|       "200",
 | |
|       "200",
 | |
|     ],
 | |
|     result: "0,1,2,3,5,4,6,7,8,9",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1", "2,7", "3", "4", "5", "6"],
 | |
|     memory: ["100", "200", "300", "400", "500", "600", "700"],
 | |
|     result: "1,0,2,3,4,5",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1,6", "2,7", "3,8", "4,1,2", "5", "6", "7", "8"],
 | |
|     memory: ["100", "200", "300", "400", "500", "600", "700", "800"],
 | |
|     result: "2,3,0,1,4,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "2", "1", "1", "1", "1"],
 | |
|     memory: ["700", "1000"],
 | |
|     result: "0,3,1,2,4,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "1", "2,1", "2,1", "3", "3"],
 | |
|     memory: ["1000", "2000", "3000"],
 | |
|     result: "0,1,2,4,3,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["2", "2", "2", "2", "2,1", "2,1", "3", "3"],
 | |
|     memory: ["1000", "600", "1000"],
 | |
|     result: "0,1,2,4,3,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "2", "2,1,1,1", "2,1", "3", "3"],
 | |
|     memory: ["1000", "1800", "1000"],
 | |
|     result: "0,1,3,2,4,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     tabs: ["1", "2", "3", "4", "5", "6", "7", "8"],
 | |
|     process: ["1", "1", "1", "2", "2,1,1,1", "2,1", "3", "3"],
 | |
|     memory: ["4000", "1800", "1000"],
 | |
|     result: "0,1,2,4,3,5,6,7",
 | |
|   },
 | |
|   {
 | |
|     // The tab "1" contains 4 frames, but its uniqueCount is 1 because
 | |
|     // all of those frames are backed by the process "1".  As a result,
 | |
|     // TabUnloader puts the tab "1" first based on the last access time.
 | |
|     tabs: ["1", "2", "3", "4", "5"],
 | |
|     process: ["1,1,1,1", "2", "3", "3", "3"],
 | |
|     memory: ["100", "100", "100"],
 | |
|     result: "0,1,2,3,4",
 | |
|   },
 | |
|   {
 | |
|     // The uniqueCount of the tab "1", "2", and "3" is 1, 2, and 3,
 | |
|     // respectively.  As a result the first three tabs are sorted as 2,1,0.
 | |
|     tabs: ["1", "2", "3", "4", "5", "6"],
 | |
|     process: ["1,7,1,7,1,1,7,1", "7,3,7,2", "4,5,7,4,6,7", "7", "7", "7"],
 | |
|     memory: ["100", "100", "100", "100", "100", "100", "100"],
 | |
|     result: "2,1,0,3,4,5",
 | |
|   },
 | |
| ];
 | |
| 
 | |
| let globalBrowser = {
 | |
|   discardBrowser() {
 | |
|     return true;
 | |
|   },
 | |
| };
 | |
| 
 | |
| add_task(async function doTests() {
 | |
|   for (let test of unloadTests) {
 | |
|     function* iterateTabs() {
 | |
|       let tabs = test.tabs;
 | |
|       for (let t = 0; t < tabs.length; t++) {
 | |
|         let tab = {
 | |
|           tab: {
 | |
|             originalIndex: t,
 | |
|             lastAccessed: Number(/^[0-9]+/.exec(tabs[t])[0]),
 | |
|             keywords: tabs[t],
 | |
|             process: "process" in test ? test.process[t] : "1",
 | |
|           },
 | |
|           memory: test.memory,
 | |
|           gBrowser: globalBrowser,
 | |
|         };
 | |
|         yield tab;
 | |
|       }
 | |
|     }
 | |
|     TestTabUnloaderMethods.iterateTabs = iterateTabs;
 | |
| 
 | |
|     let expectedOrder = "";
 | |
|     const sortedTabs = await TabUnloader.getSortedTabs(
 | |
|       0,
 | |
|       TestTabUnloaderMethods
 | |
|     );
 | |
|     for (let tab of sortedTabs) {
 | |
|       if (expectedOrder) {
 | |
|         expectedOrder += ",";
 | |
|       }
 | |
|       expectedOrder += tab.tab.originalIndex;
 | |
|     }
 | |
| 
 | |
|     Assert.equal(expectedOrder, test.result);
 | |
|   }
 | |
| });
 | 
