test_load_same_resource.html (3662B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Test loading of the same resource in multiple elements</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> 7 <script type="text/javascript" src="manifest.js"></script> 8 </head> 9 <body> 10 11 <pre id="test"> 12 <script class="testbody" type="text/javascript"> 13 14 SimpleTest.requestCompleteLog(); 15 var manager = new MediaTestManager; 16 17 function checkDuration(actual, expected, name) { 18 ok(Math.abs(actual - expected) < 0.1, 19 `${name} duration: ${actual} expected: ${expected}`); 20 } 21 22 function cloneLoaded(event) { 23 var e = event.target; 24 ok(true, `${e.token} loaded OK`); 25 checkDuration(e.duration, e._expectedDuration, e.token); 26 removeNodeAndSource(e); 27 manager.finished(e.token); 28 } 29 30 function tryClone(e) { 31 var clone = e.cloneNode(false); 32 clone.token = `${e.token}(cloned)`; 33 manager.started(clone.token); 34 manager.finished(e.token); 35 36 // Log events for debugging. 37 var events = ["suspend", "play", "canplay", "canplaythrough", "loadstart", "loadedmetadata", 38 "loadeddata", "playing", "ended", "error", "stalled", "emptied", "abort", 39 "waiting", "pause"]; 40 function logEvent(evt) { 41 var event = evt.target; 42 info(`${event.token} got ${evt.type}`); 43 } 44 events.forEach(function(event) { 45 clone.addEventListener(event, logEvent); 46 }); 47 48 49 checkDuration(e.duration, e._expectedDuration, e.token); 50 clone._expectedDuration = e._expectedDuration; 51 52 clone.addEventListener("loadeddata", cloneLoaded, {once: true}); 53 clone.addEventListener("loadstart", function(evt) { 54 info(`${evt.target.token} starts loading.`); 55 // Since there is only one H264 decoder instance, we have to delete the 56 // decoder of the original element for the cloned element to load. However, 57 // we can't delete the decoder too early otherwise cloning decoder will 58 // fail to kick in. We wait for 'loadstart' event of the cloned element to 59 // know when the decoder is already cloned and we can delete the decoder of 60 // the original element. 61 removeNodeAndSource(e); 62 }, {once: true}); 63 } 64 65 // This test checks that loading the same URI twice in different elements at the same time 66 // uses the same resource without doing another network fetch. One of the gCloneTests 67 // uses dynamic_resource.sjs to return one resource on the first fetch and a different resource 68 // on the second fetch. These resources have different lengths, so if the cloned element 69 // does a network fetch it will get a resource with the wrong length and we get a test 70 // failure. 71 72 async function initTest(test, token) { 73 var e = document.createElement("video"); 74 e.preload = "auto"; 75 e.src = test.name; 76 e._expectedDuration = test.duration; 77 ok(true, `Trying to load ${test.name}, duration=${test.duration}`); 78 e.token = token; 79 manager.started(token); 80 81 // Since 320x240.webm is less than 32KB, we need to wait for the 82 // 'suspend' event to ensure the partial block is flushed to the cache 83 // otherwise the cloned resource will create a new channel when it 84 // has no data to read at position 0. The new channel will download 85 // a different file than the original resource and fail the duration 86 // test. 87 let p1 = once(e, "loadeddata"); 88 let p2 = once(e, "suspend"); 89 await p1; 90 await p2; 91 tryClone(e); 92 } 93 94 SimpleTest.waitForExplicitFinish(); 95 SpecialPowers.pushPrefEnv( 96 {"set": [ 97 ["logging.MediaDecoder", "Debug"], 98 ["logging.HTMLMediaElement", "Debug"], 99 ["logging.MediaCache", "Debug"], 100 ]}, 101 manager.runTests.bind(manager, gCloneTests, initTest)); 102 103 </script> 104 </pre> 105 </body> 106 </html>